gchq/CyberChef · error · OperationError
Invalid secret. The input must be a valid base32 string (cha
Error message
Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).
What it means
Thrown by GenerateHOTP when the user-supplied secret cannot be parsed as a valid RFC 4648 base32 string. CyberChef decodes the input as UTF-8, trims it, uppercases it, and strips whitespace before handing it to OTPAuth.Secret.fromBase32(). If that call rejects the value (illegal characters, wrong padding, empty-after-trim edge cases), the catch block surfaces this generic OperationError. It is an expected user-input error, not an internal fault.
Source
Thrown at src/core/operations/GenerateHOTP.mjs:64
"min": 0,
"integer": true
}
];
}
/**
*
*/
run(input, args) {
const secretStr = new TextDecoder("utf-8").decode(input).trim();
let secret;
try {
secret = secretStr ?
OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) :
new OTPAuth.Secret();
} catch {
throw new OperationError("Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).");
}
const hotp = new OTPAuth.HOTP({
issuer: "",
label: args[0],
algorithm: "SHA1",
digits: args[1],
counter: args[2],
secret
});
const uri = hotp.toString();
const code = hotp.generate();
return `URI: ${uri}\n\nPassword: ${code}`;
}
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Ensure the input contains only base32 alphabet characters A-Z and 2-7 (spaces are tolerated and stripped).
- Remove any '=' padding, dashes, or non-base32 symbols from the secret.
- If you have a hex or base64 secret, convert it to base32 first using the From Hex / From Base64 operations.
Example fix
// before (hex secret passed directly) JBSWY3DPEHPK3PXP -> error if it contains '1','8','9','0' // after const clean = secret.toUpperCase().replace(/[^A-Z2-7]/g, ""); // feed only clean base32 to the operation
Defensive patterns
Strategy: validation
Validate before calling
const BASE32 = /^[A-Z2-7]+$/;
const cleaned = secretStr.toUpperCase().replace(/\s+/g, "");
if (secretStr && !BASE32.test(cleaned)) {
// do not call the operation; surface a base32 error to the user
} Type guard
function isValidBase32Secret(s) {
if (!s) return true; // empty is allowed (random secret)
return /^[A-Z2-7]+$/.test(s.toUpperCase().replace(/\s+/g, ""));
} Try / catch
try {
return OTPAuth.Secret.fromBase32(cleaned);
} catch {
throw new OperationError("Invalid secret. Use base32 A-Z and 2-7.");
} Prevention
- Normalize the secret to uppercase and strip whitespace before passing it in.
- Validate against /^[A-Z2-7]+$/ before invoking the operation.
- Convert hex/base64 secrets to base32 with the appropriate decode operations first.
When it happens
Trigger: Calling GenerateHOTP.run() with input containing characters outside A-Z and 2-7 (e.g. '0', '1', '8', '9', lowercase before uppercasing if non-ASCII present), or with malformed padding. An empty string does NOT trigger it — an empty secret produces a new random OTPAuth.Secret() instead.
Common situations: Pasting a TOTP/HOTP secret that includes spaces or dashes that survive the whitespace strip, copying a hex-encoded or base64 secret by mistake, or feeding a secret with '=' padding the library rejects.
Related errors
- Invalid secret. The input must be a valid base32 string (cha
- Unsupported Mode: (${mode})
- Invalid length type
- Length must be greater than 0
- Length must be less than ${maxLoremWords}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/0cd1f7131a282bd0.
Report an issue: GitHub.