{"record":{"id":"0ad8ecf8baec0ce8","repo":"halo-dev/halo","slug":"cookie-token-1-did-not-contain-a-valid-number-co","errorCode":null,"errorMessage":"Cookie token[1] did not contain a valid number (contained '{}')","messagePattern":"Cookie token\\[1\\] did not contain a valid number \\(contained '(.+?)'\\)","errorType":"validation","errorClass":"InvalidCookieException","httpStatus":null,"severity":"warning","filePath":"application/src/main/java/run/halo/app/security/authentication/rememberme/TokenBasedRememberMeServices.java","lineNumber":196,"sourceCode":"                                    throw new InvalidCookieException(\n                                            \"Cookie contained signature '\" + actualTokenSignature\n                                                    + \"' but expected '\"\n                                                    + expectedTokenSignature + \"'\");\n                                }\n                            })\n                            .thenReturn(userDetails);\n                });\n    }\n\n    protected boolean isTokenExpired(long tokenExpiryTime) {\n        return tokenExpiryTime < System.currentTimeMillis();\n    }\n\n    private long getTokenExpiryTime(String[] cookieTokens) {\n        try {\n            return Long.parseLong(cookieTokens[1]);\n        } catch (NumberFormatException nfe) {\n            throw new InvalidCookieException(\n                    \"Cookie token[1] did not contain a valid number (contained '\" + cookieTokens[1] + \"')\");\n        }\n    }\n\n    protected Mono<Authentication> createSuccessfulAuthentication(ServerWebExchange exchange, UserDetails user) {\n        return getKey().map(key -> new RememberMeAuthenticationToken(\n                key, user, this.authoritiesMapper.mapAuthorities(user.getAuthorities())));\n    }\n\n    private boolean isValidCookieTokensLength(String[] cookieTokens) {\n        return cookieTokens.length == 3 || cookieTokens.length == 4;\n    }\n\n    @Override\n    public Mono<Void> loginFail(ServerWebExchange exchange) {\n        log.debug(\"Interactive login attempt was unsuccessful.\");\n        cancelCookie(exchange);\n        return parameterRequestCache.saveParameter(exchange, parameterName);","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/application/src/main/java/run/halo/app/security/authentication/rememberme/TokenBasedRememberMeServices.java#L178-L214","documentation":"After Base64-decoding the remember-me cookie and splitting on the delimiter, getTokenExpiryTime() parses token slot [1] as a long (epoch millis). If Long.parseLong throws NumberFormatException, the slot is not a valid expiry timestamp and an InvalidCookieException is thrown. The expiry is the second token in the cookie payload (index 1).","triggerScenarios":"A remember-me cookie whose decoded second colon-delimited token is non-numeric: a truncated, tampered, or manually-constructed cookie; a cookie produced by an incompatible/older cookie format; URL-decoding (URLDecoder.decode on each token) mangling the value. Reached via processAutoLoginCookie -> getTokenExpiryTime.","commonSituations":"Cookie altered by a browser extension or proxy; copy-paste of a cookie between users; downgrade/upgrade across a version that changed the token layout; locale-specific characters surviving into the token.","solutions":["Treat it as a bad cookie: the user re-authenticates and a correctly-formatted cookie is issued (handleError cancels the cookie automatically).","If reproducible across many users, check whether a proxy/CDN is rewriting or truncating the cookie value.","Verify you are not running mixed Halo versions that emit different token layouts.","Ensure the cookie is not being URL-encoded twice in transit."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rely on TokenBasedRememberMeServices.handleError which cancels the cookie:\n.onErrorResume(InvalidCookieException.class, ex -> {\n    log.debug(\"Malformed remember-me cookie rejected: {}\", ex.getMessage());\n    return Mono.empty();\n})","preventionTips":["Do not manually edit or truncate remember-me cookie values.","Ensure reverse proxies do not rewrite or trim the cookie payload.","Run a single Halo version across nodes so the token layout is consistent.","Treat any InvalidCookieException as a recoverable 'please log in again' condition."],"tags":["security","authentication","cookie","remember-me","validation"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}