{"record":{"id":"b4e02647eb426a56","repo":"apache/hadoop","slug":"invalid-token-string-missing-attributes","errorCode":null,"errorMessage":"Invalid token string, missing attributes","messagePattern":"Invalid token string, missing attributes","errorType":"exception","errorClass":"AuthenticationException","httpStatus":401,"severity":"error","filePath":"hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java","lineNumber":214,"sourceCode":"  @Override\n  public String toString() {\n    return tokenStr;\n  }\n\n  public static AuthToken parse(String tokenStr) throws AuthenticationException {\n    if (tokenStr.length() >= 2) {\n      // strip the \\\" at the two ends of the tokenStr\n      if (tokenStr.charAt(0) == '\\\"' &&\n          tokenStr.charAt(tokenStr.length()-1) == '\\\"') {\n        tokenStr = tokenStr.substring(1, tokenStr.length()-1);\n      }\n    } \n    Map<String, String> map = split(tokenStr);\n    // remove the signature part, since client doesn't care about it\n    map.remove(\"s\");\n\n    if (!map.keySet().containsAll(ATTRIBUTES)) {\n      throw new AuthenticationException(\"Invalid token string, missing attributes\");\n    }\n    long expires = Long.parseLong(map.get(EXPIRES));\n    AuthToken token = new AuthToken(map.get(USER_NAME), map.get(PRINCIPAL), map.get(TYPE));\n    //process optional attributes\n    if (map.containsKey(MAX_INACTIVES)) {\n      long maxInactives = Long.parseLong(map.get(MAX_INACTIVES));\n      token.setMaxInactives(maxInactives);\n    }\n    token.setExpires(expires);\n    return token;\n  }\n\n  /**\n   * Splits the string representation of a token into attributes pairs.\n   *\n   * @param tokenStr string representation of a token.\n   *\n   * @return a map with the attribute pairs of the token.","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/AuthToken.java#L196-L232","documentation":"AuthToken.parse() decodes the wire form of a hadoop-auth signed authentication token ('u=<user>&p=<principal>&t=<type>&e=<expires>[&i=<maxInactives>]&s=<signature>'). The signature pair 's' is intentionally removed, but the four attributes u, p, t and e are mandatory. If the key/value map produced by split() lacks any of them, this AuthenticationException is thrown.","triggerScenarios":"Calling AuthToken.parse(tokenStr) / AuthenticationToken.parse() on a string such as 'u=alice&e=1234' that is missing the principal ('p') or type ('t') pair; a cookie truncated in transit so the last attribute pairs are cut off; a token string assembled by hand or by an incompatible older hadoop-auth version that did not write the 't' (type) attribute.","commonSituations":"Reverse proxies or browsers truncating an oversized 'hadoop.auth' cookie; custom clients constructing token strings manually instead of using AuthenticationFilter login; version skew between token producer and verifier after the typed-token change (HADOOP-14697) added the 't' attribute; tests that strip or edit token fields.","solutions":["Log the raw token string and confirm every required pair u=, p=, t=, e= is present before it reaches AuthToken.parse","Discard the malformed cookie and force re-authentication through the AuthenticationFilter to mint a fresh token","If producer and consumer run different Hadoop versions, align them or configure matching AuthenticationToken semantics so the 't' attribute is always written","Check for cookie-size limits or proxy rewriting that truncates the 'hadoop.auth' cookie value"],"exampleFix":"// before\nAuthToken token = AuthToken.parse(\"u=alice&e=1893456000000\");\n\n// after: include all required attributes u, p, t, e\nAuthToken token = AuthToken.parse(\"u=alice&p=alice&t=hadoop&e=1893456000000\");","handlingStrategy":"validation","validationCode":"boolean isParseableTokenString(String s) {\n  if (s == null) return false;\n  String t = s.length() >= 2 && s.charAt(0) == '\"' && s.charAt(s.length()-1) == '\"'\n      ? s.substring(1, s.length()-1) : s;\n  java.util.Map<String,String> m = new java.util.HashMap<>();\n  for (String part : t.split(\"&\")) {\n    int i = part.indexOf('=');\n    if (i <= 0) return false;\n    m.put(part.substring(0, i), part.substring(i+1));\n  }\n  m.remove(\"s\");\n  return m.keySet().containsAll(java.util.Arrays.asList(\"u\",\"p\",\"t\",\"e\"));\n}","typeGuard":null,"tryCatchPattern":"try { AuthToken token = AuthToken.parse(str); } catch (AuthenticationException e) { /* log str, clear cookie, force re-authentication */ }","preventionTips":["Never hand-assemble token strings; obtain tokens from the AuthenticationFilter login flow","Keep token producer and consumer on compatible hadoop-auth versions","Watch for proxy truncation of the hadoop.auth cookie when symptoms appear"],"tags":["hadoop-auth","authentication","token-parsing","cookie"],"backgroundTag":"auth-token-parse-failure","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}