{"record":{"id":"f576190129e653b8","repo":"apache/hadoop","slug":"invalid-permissions-mode-provided-while-trying-to","errorCode":null,"errorMessage":"Invalid permissions mode provided while trying to createPermissions","messagePattern":"Invalid permissions mode provided while trying to createPermissions","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/LocalKeyStoreProvider.java","lineNumber":86,"sourceCode":"  @Override\n  protected boolean keystoreExists() throws IOException {\n    /* The keystore loader doesn't handle zero length files. */\n    return file.exists() && (file.length() > 0);\n  }\n\n  @Override\n  protected InputStream getInputStreamForFile() throws IOException {\n    InputStream is = Files.newInputStream(file.toPath());\n    return is;\n  }\n\n  @Override\n  protected void createPermissions(String perms) throws IOException {\n    int mode = 700;\n    try {\n      mode = Integer.parseInt(perms, 8);\n    } catch (NumberFormatException nfe) {\n      throw new IOException(\"Invalid permissions mode provided while \"\n          + \"trying to createPermissions\", nfe);\n    }\n    permissions = modeToPosixFilePermission(mode);\n  }\n\n  @Override\n  protected void stashOriginalFilePermissions() throws IOException {\n    // save off permissions in case we need to\n    // rewrite the keystore in flush()\n    if (!Shell.WINDOWS) {\n      Path path = Paths.get(file.getCanonicalPath());\n      permissions = Files.getPosixFilePermissions(path);\n    } else {\n      // On Windows, the JDK does not support the POSIX file permission APIs.\n      // Instead, we can do a winutils call and translate.\n      String[] cmd = Shell.getGetPermissionCommand();\n      String[] args = new String[cmd.length + 1];\n      System.arraycopy(cmd, 0, args, 0, cmd.length);","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/LocalKeyStoreProvider.java#L68-L104","documentation":"LocalKeyStoreProvider.createPermissions() parses its argument as a base-8 integer (Integer.parseInt(perms, 8)); a NumberFormatException is wrapped into this IOException. In stock Hadoop the caller passes the constant '600' and can never fail - this error only fires in a subclass or caller that passes a non-octal permission string (e.g. 'rw-------', '0x1C0', empty).","triggerScenarios":"A custom subclass of LocalKeyStoreProvider/AbstractJavaKeyStoreProvider overriding the caller and passing symbolic or hex permission strings; refactoring that turns '600' into a symbolic mode; passing a permissions string sourced from config without validation.","commonSituations":"Teams extending the credential provider SPI; porting code that stored permissions as 'rwx------' strings; config-driven permission values injected unvalidated.","solutions":["Pass strictly octal digit strings: '600', '640', '440', '700'","Validate before calling: perms.matches(\"[0-7]{3,4}\")","Convert symbolic modes to octal in your layer (FsPermission.valueOf(...).toOctal()) before invoking createPermissions"],"exampleFix":"// before (custom subclass)\ncreatePermissions(\"rw-------\");   // NumberFormatException -> IOException\n\n// after\ncreatePermissions(FsPermission.valueOf(\"rw-------\").toOctal());   // \"600\"","handlingStrategy":"validation","validationCode":"// Subclass authors: validate the mode string before calling createPermissions\nstatic void assertOctalMode(String perms) {\n  if (perms == null || !perms.matches(\"[0-7]{3,4}\")) {\n    throw new IllegalArgumentException(\"Permission mode must be octal digits, e.g. 600: \" + perms);\n  }\n}","typeGuard":"boolean isValidOctalMode(String perms) {\n  return perms != null && perms.matches(\"[0-7]{3,4}\");\n}","tryCatchPattern":"try {\n  createPermissions(perms);\n} catch (IOException ex) {\n  if (ex.getCause() instanceof NumberFormatException) {\n    // caller passed a non-octal mode string; fix the value, do not retry with the same input\n  } else { throw ex; }\n}","preventionTips":["Only pass literal octal strings ('600', '640') through createPermissions APIs","Convert symbolic modes with FsPermission.valueOf(sym).toOctal() at the boundary","Add a unit test for any subclass overriding permission handling"],"tags":["hadoop","credential-provider","permissions","octal","subclass"],"backgroundTag":"invalid-octal-mode","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}