Updated 2026-09-25
Token errors
App with login: the widget cannot verify the signed client token.
Symptom
The site uses App with login. The widget is on the page, and sending or opening it says "Could not verify your identity. Refresh the page and try again." The API answer is MDF-AUTH-001, "You need to sign in."
The token is base64url JSON (email, name, exp) plus a dot plus base64url HMAC-SHA256 of that payload, signed with MODIFEE_SECRET. exp is a unix time, 24 hours ahead when you use the install snippet.
Causes
data-token is empty
Confirm. View source on the signed-in page. The script has data-project and data-token="", or no data-token. The console says "Modifee: data-project and data-token are required". For App with login, the button does not mount without a token.
Fix. Compute the token on the server for the signed-in user and set data-token on that response. Never send MODIFEE_SECRET to the browser. See the install page for your stack.
The signature does not match
Modifee decrypts the current project key and checks the HMAC. A mismatch throws "Invalid client token", which the widget shows as the identity sentence above.
Confirm. The token is present and well formed, and Signing secret was regenerated, or the server is signing with a different value than the one in the MODIFEE_SECRET block.
Three usual mismatches:
- The server still has the previous secret. Regenerating the key invalidates every token signed with the old one. The line "MODIFEE_SECRET set on Vercel ✓" only means the new value is stored. The running deployment keeps the old value until it is redeployed. See Secret and redeploy.
- Production and Preview hold different values. Modifee writes both targets together. A manual edit on one target, or a preview deployment from before the push, signs with the other secret.
- The token was signed with a secret from another project.
Fix. Copy the current MODIFEE_SECRET, set it on the server that signs the token, redeploy production and preview, then load the page again so a new token is issued.
The token is expired
Confirm. Decode the payload. exp is less than or equal to the current unix time. The snippet sets exp to now plus 86400 seconds. The widget shows the same identity sentence.
Fix. Render a new token on each request. Do not cache the HTML that contains it.
The signing server's clock is ahead
Modifee compares exp to its own clock. There is no grace period. If the server that signs the token is ahead of real time, exp can already be in the past when the browser sends it.
Confirm. Decode exp and compare it to the current unix time on a clock you trust. The token fails as soon as it is issued, and a short delay makes it valid, or the opposite: it lasts far longer than 24 hours when the signing clock is behind.
Fix. Sync the signing server with NTP, then issue a new token.
A cached page served someone else's token
Confirm. Two users receive the same data-token, or a signed-out user receives a token. The page is statically generated, cached at the CDN, or sent with a public Cache-Control. On the App Router, the layout or page that reads the session is missing export const dynamic = "force-dynamic".
Fix. Render that page on every request and do not cache it. See the cache warning on the install page for your stack. MDF-AUTH-001.