{"record":{"id":"47ed48e8830231c2","repo":"apache/hadoop","slug":"the-authorization-provider-does-not-implement-the","errorCode":null,"errorMessage":"The authorization provider does not implement the checkPermissionWithContext(AuthorizationContext) API.","messagePattern":"The authorization provider does not implement the checkPermissionWithContext\\(AuthorizationContext\\) API\\.","errorType":"exception","errorClass":"AccessControlException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeAttributeProvider.java","lineNumber":404,"sourceCode":"    public abstract void checkPermission(String fsOwner, String supergroup,\n        UserGroupInformation callerUgi, INodeAttributes[] inodeAttrs,\n        INode[] inodes, byte[][] pathByNameArr, int snapshotId, String path,\n        int ancestorIndex, boolean doCheckOwner, FsAction ancestorAccess,\n        FsAction parentAccess, FsAction access, FsAction subAccess,\n        boolean ignoreEmptyDir)\n            throws AccessControlException;\n\n    /**\n     * Checks permission on a file system object. Has to throw an Exception\n     * if the filesystem object is not accessible by the calling Ugi.\n     * @param authzContext an {@link AuthorizationContext} object encapsulating\n     *                     the various parameters required to authorize an\n     *                     operation.\n     * @throws AccessControlException\n     */\n    default void checkPermissionWithContext(AuthorizationContext authzContext)\n        throws AccessControlException {\n      throw new AccessControlException(\"The authorization provider does not \"\n          + \"implement the checkPermissionWithContext(AuthorizationContext) \"\n          + \"API.\");\n    }\n\n    /**\n     * Checks if the user is a superuser or belongs to superuser group.\n     * It throws an AccessControlException if user is not a superuser.\n     *\n     * @param authzContext an {@link AuthorizationContext} object encapsulating\n     *                     the various parameters required to authorize an\n     *                     operation.\n     * @throws AccessControlException - if user is not a super user or part\n     * of the super user group.\n     */\n    default void checkSuperUserPermissionWithContext(\n        AuthorizationContext authzContext)\n        throws AccessControlException {\n      UserGroupInformation callerUgi = authzContext.getCallerUgi();","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeAttributeProvider.java#L386-L422","documentation":"INodeAttributeProvider.AccessControlEnforcer.checkPermissionWithContext(AuthorizationContext) is a Java default method whose only behavior is to throw AccessControlException. If the authorization provider configured via dfs.namenode.inode.attributes.provider.class does not override this newer context-based API, every code path that calls it (notably HDFS Router-based federation permission checks and newer NameNode internals) fails with this error even though the legacy checkPermission methods work.","triggerScenarios":"A custom INodeAttributeProvider (Ranger/Sentry-style plugin or in-house enforcer) implements only the legacy checkPermission(String, String, INodeAttributes, ...) and a Router or upgraded NameNode invokes checkPermissionWithContext; deploying a provider jar compiled against an older hadoop-hdfs than the running cluster.","commonSituations":"Upgrading Hadoop (or adding HDFS Router federation) while keeping a third-party authz plugin built for the old API surface; integrating an internal authorization service that was written before the AuthorizationContext API existed.","solutions":["Override checkPermissionWithContext(AuthorizationContext) in the custom AccessControlEnforcer — usually by unpacking the context and delegating to the existing permission logic — then redeploy the provider jar","Upgrade the provider to a release built against the running Hadoop version","If the provider is unnecessary, remove dfs.namenode.inode.attributes.provider.class from the NameNode/Router config"],"exampleFix":"// before: only legacy API implemented -> default method throws\nclass MyEnforcer extends INodeAttributeProvider.AccessControlEnforcer {\n  @Override public void checkPermission(String caller, String inode, ...\n      throws AccessControlException) { /* legacy logic */ }\n}\n\n// after: bridge the context API to existing logic\nclass MyEnforcer extends INodeAttributeProvider.AccessControlEnforcer {\n  @Override public void checkPermissionWithContext(AuthorizationContext ctx)\n      throws AccessControlException {\n    checkPermission(ctx.getCallerUgi().getShortUserName(),\n        ctx.getInodePath(), ctx.getInodeAttrs(), ctx.getAction());\n  }\n}","handlingStrategy":"validation","validationCode":"// Deploy-time check: does the configured enforcer actually override the context API?\nMethod m = enforcer.getClass().getMethod(\n    \"checkPermissionWithContext\", AuthorizationContext.class);\nif (m.getDeclaringClass()\n    .equals(INodeAttributeProvider.AccessControlEnforcer.class)) {\n  throw new RuntimeException(enforcer.getClass().getName()\n      + \" does not implement checkPermissionWithContext(AuthorizationContext)\");\n}","typeGuard":"boolean supportsContextApi(INodeAttributeProvider.AccessControlEnforcer e) {\n  try {\n    Method m = e.getClass().getMethod(\n        \"checkPermissionWithContext\", AuthorizationContext.class);\n    return !m.getDeclaringClass()\n        .equals(INodeAttributeProvider.AccessControlEnforcer.class);\n  } catch (NoSuchMethodException ex) {\n    return false;\n  }\n}","tryCatchPattern":"catch (AccessControlException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\n      \"checkPermissionWithContext\")) {\n    // provider/API mismatch: fix the deployment, do not retry\n    throw new IllegalStateException(\"Authorization provider incompatible \"\n        + \"with running Hadoop version; implement/upgrade the provider\", e);\n  }\n  throw e;\n}","preventionTips":["Run an integration test against a real NameNode/Router when deploying custom authz providers","Pin provider jars to the exact hadoop-hdfs version of the cluster (or compile against it)","Implement all *WithContext default methods in custom enforcers, even if only as delegating bridges"],"tags":["hdfs","authorization","provider-plugin","upgrade","default-method","rbf"],"backgroundTag":"interface-default-method-not-implemented","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}