{"record":{"id":"a78fafedbd4e610e","repo":"prestodb/presto","slug":"grantrevokeresponse-missing-success-field","errorCode":null,"errorMessage":"GrantRevokeResponse missing success field","messagePattern":"GrantRevokeResponse missing success field","errorType":"exception","errorClass":"MetaException","httpStatus":null,"severity":"error","filePath":"presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastoreClient.java","lineNumber":432,"sourceCode":"            }\n        }\n        createGrant(role, granteeName, granteeType, grantorName, grantorType, grantOption);\n    }\n\n    private void createGrant(String role, String granteeName, PrincipalType granteeType, String grantorName, PrincipalType grantorType, boolean grantOption)\n            throws TException\n    {\n        GrantRevokeRoleRequest request = new GrantRevokeRoleRequest();\n        request.setRequestType(GrantRevokeType.GRANT);\n        request.setRoleName(role);\n        request.setPrincipalName(granteeName);\n        request.setPrincipalType(granteeType);\n        request.setGrantor(grantorName);\n        request.setGrantorType(grantorType);\n        request.setGrantOption(grantOption);\n        GrantRevokeRoleResponse response = client.grant_revoke_role(request);\n        if (!response.isSetSuccess()) {\n            throw new MetaException(\"GrantRevokeResponse missing success field\");\n        }\n    }\n\n    @Override\n    public void revokeRole(String role, String granteeName, PrincipalType granteeType, boolean grantOption)\n            throws TException\n    {\n        List<RolePrincipalGrant> grants = listRoleGrants(granteeName, granteeType);\n        RolePrincipalGrant currentGrant = null;\n        for (RolePrincipalGrant grant : grants) {\n            if (grant.getRoleName().equals(role)) {\n                currentGrant = grant;\n                break;\n            }\n        }\n\n        if (currentGrant == null) {\n            return;","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastoreClient.java#L414-L450","documentation":"ThriftHiveMetastoreClient.createGrant sends a GrantRevokeRoleRequest to the Hive metastore via grant_revoke_role. The response object carries an optional 'success' field; if the metastore (typically an older Hive version) never sets it, Presto cannot confirm the grant succeeded and throws MetaException(\"GrantRevokeResponse missing success field\"). This is a defensive protocol check against metastores that don't honor the response contract.","triggerScenarios":"Calling grantRole (GRANT role TO user/role in Presto), which calls createGrant, when the metastore's GrantRevokeRoleResponse has success unset — i.e. a Hive metastore version whose thrift definition predates the success field, or a metastore implementation that returns a default-constructed response.","commonSituations":"Older Hive metastore (pre-2.x thrift definitions) behind a newer Presto client; third-party metastore services (e.g. AWS Glue bridge, Waggle Dance) that don't populate the success field; GRANT statements run against a mismatched metastore version.","solutions":["Upgrade the Hive metastore to a version whose grant_revoke_role sets the success field in GrantRevokeRoleResponse.","Verify the actual grant took effect with SHOW GRANTS / listRoleGrants; if it did, the error is a false negative from the missing field.","Check for a proxy/metastore-routing layer (Waggle Dance, Glue catalog) stripping or not propagating the response field, and bypass or upgrade it.","As a workaround, create the grant directly in Hive and verify in Presto with SHOW GRANTS."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before issuing GRANT, verify the metastore supports role grants\nList<String> roles = metastore.listRoleNames(); // throws/errs if RBAC unsupported\n// and check metastore version >= 2.x if GrantRevokeRoleResponse.success is required","typeGuard":null,"tryCatchPattern":"try {\n    accessControl.grantRoles(...);\n}\ncatch (PrestoException e) {\n    if (e.getCause() instanceof MetaException\n            && e.getCause().getMessage().contains(\"missing success field\")) {\n        // verify actual state, e.g. SHOW GRANTS, and warn about metastore version\n    }\n    throw e;\n}","preventionTips":["Run a metastore version that populates GrantRevokeRoleResponse.success (Hive 2.x+).","Test GRANT/REVOKE against staging metastores before production role management.","Avoid metastore proxies that rewrite or drop thrift response fields.","Verify grants with SHOW GRANTS instead of trusting only the RPC result."],"tags":["hive-metastore","thrift","role-grant","version-compatibility"],"backgroundTag":"thrift-response-schema-mismatch","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}