Impala query failed with error “IllegalArgumentException: Value cannot be empty”

Impala query failed with error “IllegalArgumentException: Value cannot be empty”

This article explains what to do to fix the issue that when running “SHOW DATABASES” or other simply Impala queries, Impala complains “ERROR: IllegalArgumentException: Value cannot be empty”. The full stack trace showing in the Impala Daemon log as follows:
I0620 10:46:08.436385 47131 Frontend.java:818] analyze query show databases
I0620 10:46:08.437651 47131 jni-util.cc:177] java.lang.IllegalArgumentException: Value cannot be empty
at org.apache.sentry.provider.file.KeyValue.(KeyValue.java:41)
at org.apache.sentry.policy.db.DBWildcardPrivilege.(DBWildcardPrivilege.java:62)
at org.apache.sentry.policy.db.DBWildcardPrivilege$DBWildcardPrivilegeFactory.createPrivilege(DBWildcardPrivilege.java:167)
at org.apache.sentry.provider.common.ResourceAuthorizationProvider$2.apply(ResourceAuthorizationProvider.java:131)
at org.apache.sentry.provider.common.ResourceAuthorizationProvider$2.apply(ResourceAuthorizationProvider.java:128)
at com.google.common.collect.Iterators$8.next(Iterators.java:812)
at org.apache.sentry.provider.common.ResourceAuthorizationProvider.doHasAccess(ResourceAuthorizationProvider.java:107)
at org.apache.sentry.provider.common.ResourceAuthorizationProvider.hasAccess(ResourceAuthorizationProvider.java:91)
at com.cloudera.impala.authorization.AuthorizationChecker.hasAccess(AuthorizationChecker.java:171)
at com.cloudera.impala.service.Frontend.getDbNames(Frontend.java:630)
at com.cloudera.impala.service.JniFrontend.getDbNames(JniFrontend.java:272)
This happens in a cluster with Kerberos and Sentry enabled. To confirm if the issue is the same as mine, follow the steps below:
  1. Run “SHOW CURRENT ROLES;” command in impala, and capture the role name
  2. Log into Sentry’s Database. I am using MySQL, so my example query will be based on MySQL below
  3. Once logs in, please run the following query:
    SELECT 
    r.ROLE_ID, r.ROLE_NAME, PRIVILEGE_SCOPE, SERVER_NAME, 
    DB_NAME, TABLE_NAME, COLUMN_NAME, URI, ACTION 
    FROM SENTRY_ROLE r 
    JOIN SENTRY_ROLE_DB_PRIVILEGE_MAP m ON (r.ROLE_ID = m.ROLE_ID) 
    JOIN SENTRY_DB_PRIVILEGE p ON (m.DB_PRIVILEGE_ID = p.DB_PRIVILEGE_ID) 
    WHERE r.ROLE_NAME = '';
    
  4. My output looks like the following:
    +---------+----------------+-----------------+-----------------+-------------+-------------+------------+-------------+--------------------------+--------+
    | ROLE_ID | ROLE_NAME      | DB_PRIVILEGE_ID | PRIVILEGE_SCOPE | SERVER_NAME | DB_NAME     | TABLE_NAME | COLUMN_NAME | URI                      | ACTION |
    +---------+----------------+-----------------+-----------------+-------------+-------------+------------+-------------+--------------------------+--------+
    |       1 | test_role      | 1               | URI             | server1     | __NULL__    | __NULL__   | __NULL__    | __NULL__                 | all    |
    +---------+----------------+-----------------+-----------------+-------------+-------------+------------+-------------+--------------------------+--------+
    
    And there is only one privilege for this role and scope is URI. Notice that all values for this role are “__NULL__”?
If you have similar output as above, then the fix will be simple. Follow the steps below:
  1. BACKUP Sentry DB again just before you about to do the change (a must do before you make any changes to any production Database)
  2. Run the following query against Sentry Database to update the URI value:
    UPDATE SENTRY_DB_PRIVILEGE set URI = 'hdfs:///dummy' where DB_PRIVILEGE_ID = 1;
    
    update the DB_PRIVILEGE_ID to match in your own case.
  3. Connect to impala-shell using the user who has admin access to sentry
  4. Run ‘INVALIDATE METADATA’ to update the metadata we just changed
  5. Test again using the user who belongs to role “unixadmins”, issue should be resolved
After this change the role will only have access to dummy URI “hdfs:///dummy”, no databases and tables, but you can grant whatever you want to the role afterwards.

Loading

2 Comments

    1. Eric Lin

      Hi Steve,

      Did you mean below query:

      SELECT
      r.ROLE_ID, r.ROLE_NAME, PRIVILEGE_SCOPE, SERVER_NAME,
      DB_NAME, TABLE_NAME, COLUMN_NAME, URI, ACTION
      FROM SENTRY_ROLE r
      JOIN SENTRY_ROLE_DB_PRIVILEGE_MAP m ON (r.ROLE_ID = m.ROLE_ID)
      JOIN SENTRY_DB_PRIVILEGE p ON (m.DB_PRIVILEGE_ID = p.DB_PRIVILEGE_ID)
      WHERE r.ROLE_NAME = ‘‘;

      ?

      It is in MySQL, you don’t need double quotes, you will need double quotes if you use PostgreSQL.

Leave a Reply

Your email address will not be published. Required fields are marked *

My new Snowflake Blog is now live. I will not be updating this blog anymore but will continue with new contents in the Snowflake world!