Huny's Dev Blog
huny.dev

Cloudflare Turnstile Server Validation: Siteverify, Expiration, and Duplicate Submissions

Validate Turnstile tokens on the server and handle expiration, duplicate submissions, test keys, and idempotency boundaries.

Hun Jang
Hun Jang Nov 14, 2026

A successful Cloudflare Turnstile widget does not by itself make a form submission trustworthy. The server must validate the browser's token with the Siteverify API and only perform the protected action, such as signup or a contact request, after validation succeeds.

AI-generated illustration of a browser token being verified by a server

Validate the token on the server

By default, the widget adds a cf-turnstile-response field to the form. The server receives it and POSTs it with the secret key to Siteverify. The sitekey is public, but keep the secret in a secure server-side store such as an environment variable; never put it in client code or logs. An endpoint can receive direct requests that bypass the widget, so a client-side success callback alone is insufficient.

Validation example and boundaries

This illustrative Node.js function checks the response. Replace example.com with the widget's expected hostname and load the secret from server configuration. The caller passes the token received from the form and performs the action only if the function returns true.

The function rejects timeouts, network errors, HTTP failures, and failed validation. In production, tell users they can retry and record error categories without tokens or secrets. Compare the response hostname exactly against the expected host; if the widget sets an action, also compare the returned action against the server's expected value. This example does not set an action. Form validation, authentication and authorization, CSRF protection, and rate limiting remain separate requirements. Response fields and error codes

Expiration and duplicate submissions

A token is valid for 300 seconds after issuance and is intended for one validation. If an old form or a retry produces timeout-or-duplicate, reset the widget using turnstile.reset() to obtain a new token. When a network failure leaves the validation result unknown, Siteverify supports an idempotency_key UUID for retries. The function above does not retry automatically.

Cloudflare says redemption state propagates with eventual consistency, so validations close together can both succeed. For payments or orders, do not rely on single-use tokens for duplicate prevention: implement separate operation-level idempotency keys and atomic state changes on the server. Token reuse and network convergence

Testing before production

Use official test keys to exercise success, failure, and duplicate-token paths. A dummy token from a test sitekey must be validated with a test secret; production and test credentials cannot be mixed. Successful test responses always use example.com as the hostname and omit action and cdata, so verify real hostname and action checks separately in an environment using real keys. Never deploy test keys to production.

Based on official documentation checked November 14, 2026. The example is illustrative and was not run against the Turnstile service.

한국어 버전: Cloudflare Turnstile 서버 검증: Siteverify와 토큰 만료·중복 처리Cloudflare Turnstile 서버 검증: Siteverify와 토큰 만료·중복 처리

추천 글