transloadit/uppy · error · Error
Invalid token payload
Error message
Invalid token payload
What it means
verifyJwtToken runs jwt.verify and then requires the decoded payload to be a non-null object containing a `data` property. A token that verifies cryptographically but lacks the expected { data: ... } shape (or decodes to a primitive/string) throws 'Invalid token payload'.
Source
Thrown at packages/@uppy/companion/src/server/helpers/jwt.ts:39
// there's no way for them to retry their failed files.
// With 400 days, there's still a theoretical possibility but very low.
export const MAX_AGE_REFRESH_TOKEN = 60 * 60 * 24 * 400
export const MAX_AGE_24H = 60 * 60 * 24
type EncryptionSecret = string | Buffer
const generateToken = (
data: unknown,
secret: EncryptionSecret,
maxAge: number,
): string => {
return jwt.sign({ data }, secret, { expiresIn: maxAge })
}
const verifyJwtToken = (token: string, secret: EncryptionSecret) => {
const decoded = jwt.verify(token, secret, {})
if (!decoded || typeof decoded !== 'object' || !('data' in decoded)) {
throw new Error('Invalid token payload')
}
return decoded['data']
}
export const generateEncryptedToken = (
payload: unknown,
secret: EncryptionSecret,
maxAge = MAX_AGE_24H,
): string => {
// return payload // for easier debugging
return encrypt(generateToken(payload, secret, maxAge), secret)
}
export const generateEncryptedAuthToken = (
payload: unknown,
secret: EncryptionSecret,
maxAge?: number,
): string => {View on GitHub (pinned to 5d4dedd02a)
Solutions
- Use the library's own token generators (generateToken/generateEncryptedToken) instead of hand-signing JWTs
- Ensure the signed payload wraps data as { data: ... }
- Check for mixed Uppy versions between token producer and consumer
Example fix
// before
const token = jwt.sign({ userId: 1 }, secret)
// after
import { generateToken } from '../helpers/jwt'
const token = generateToken({ userId: 1 }, secret) // signs { data: { userId: 1 } } Defensive patterns
Strategy: try-catch
Validate before calling
import jwt from 'jsonwebtoken'
const shapeOk = (token: string, secret: string) => {
const d = jwt.decode(token)
return typeof d === 'object' && d !== null && 'data' in d
} Type guard
const hasDataPayload = (d: unknown): d is { data: unknown } =>
typeof d === 'object' && d !== null && 'data' in d; Try / catch
try { verifyEncryptedToken(token, secret) } catch (err) {
if (err.message === 'Invalid token payload') { /* regenerate token with proper helpers */ }
} Prevention
- Only mint tokens with the library's generate* helpers
- Keep token producer and consumer on the same Uppy version
When it happens
Trigger: Passing a JWT that was signed by the same secret but with a different payload schema (e.g. { foo: 1 } or a plain string payload) to endpoints that call verifyJwtToken/verifyEncryptedToken.
Common situations: Custom code signing its own tokens with companion's secret, version drift where token payload format changed, or accidentally sending an unrelated JWT (auth token) where an uppy token is expected.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No payload
- Invalid token payload: expected string
- Missing token payload for provider ${providerName}
- File data is missing for file ${options.file.id}
- Missing S3 object key for aborting upload
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/c9e130509b4f8224.
Report an issue: GitHub.