prestodb/presto · error · PrestoException

HIVE_METASTORE_ERROR

HIVE_METASTORE_ERROR

Error message

HIVE_METASTORE_ERROR: ${e}

What it means

ThriftHiveMetastore.getPrimaryKey wraps any TException raised by the underlying metastore client when fetching a table's primary-key metadata into a PrestoException with code HIVE_METASTORE_ERROR. It signals that the Thrift RPC itself failed (transport, protocol, or metastore-side error), not that the table lacks a primary key.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java:253

            Optional<PrimaryKeysResponse> pkResponse = retry()
                    .stopOnIllegalExceptions()
                    .run("getPrimaryKey", stats.getGetPrimaryKey().wrap(() ->
                            getMetastoreClientThenCall(metastoreContext, client -> client.getPrimaryKey(dbName, tableName))));

            if (!pkResponse.isPresent() || pkResponse.get().getPrimaryKeys().size() == 0) {
                return Optional.empty();
            }

            List<SQLPrimaryKey> pkCols = pkResponse.get().getPrimaryKeys();
            boolean isEnabled = pkCols.get(0).isEnable_cstr();
            boolean isRely = pkCols.get(0).isRely_cstr();
            boolean isEnforced = pkCols.get(0).isValidate_cstr();
            String pkName = pkCols.get(0).getPk_name();
            LinkedHashSet<String> keyCols = pkCols.stream().map(SQLPrimaryKey::getColumn_name).collect(toCollection(LinkedHashSet::new));
            return Optional.of(new PrimaryKeyConstraint<>(Optional.of(pkName), keyCols, isEnabled, isRely, isEnforced));
        }
        catch (TException e) {
            throw new PrestoException(HIVE_METASTORE_ERROR, e);
        }
        catch (Exception e) {
            throw propagate(e);
        }
    }

    @Override
    public List<UniqueConstraint<String>> getUniqueConstraints(MetastoreContext metastoreContext, String dbName, String tableName)
    {
        try {
            Optional<UniqueConstraintsResponse> uniqueConstraintsResponse = retry()
                    .stopOnIllegalExceptions()
                    .run("getUniqueConstraints", stats.getGetUniqueConstraints().wrap(() ->
                            getMetastoreClientThenCall(metastoreContext, client -> client.getUniqueConstraints("hive", dbName, tableName))));

            if (!uniqueConstraintsResponse.isPresent() || uniqueConstraintsResponse.get().getUniqueConstraints().size() == 0) {
                return ImmutableList.of();
            }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Read the cause chained in the PrestoException — it names the real TException; fix transport (connectivity) or API-mismatch issues accordingly
  2. Retry the operation; transient thrift failures are often resolved by Presto's built-in metastore retry on the next attempt
  3. If the metastore version predates Hive 2.x transactional constraint APIs, upgrade the metastore or avoid reading PK metadata for those catalogs
  4. Increase hive.metastore.thrift.client.read-timeout if the failure is a timeout on large metadata

Example fix

// before
// client version too old, RPC method missing
catch (TException e) { throw new PrestoException(HIVE_METASTORE_ERROR, e); }
// after
# upgrade Hive metastore to >= 2.2 which supports get_primary_keys
# or pin catalog so constraint lookup is skipped for legacy metastores
Defensive patterns

Strategy: retry

Validate before calling

// Check metastore reachability and version support before reading primary-key metadata
try (Socket s = new Socket()) {
    s.connect(new InetSocketAddress("metastore-host", 9083), 3000);
}
// Primary-key API requires Hive metastore >= 2.2
boolean supportsPk = metastoreHiveVersionAtLeast("2.2");
if (!supportsPk) {
    log.warn("Skipping primary-key lookup: metastore does not support constraint APIs");
}

Type guard

public static boolean isMetastoreRpcError(PrestoException e) {
    return HIVE_METASTORE_ERROR.equals(e.getErrorCode())
        && e.getCause() instanceof TException;
}

Try / catch

try {
    return thriftHiveMetastore.getPrimaryKey(tableHandle);
} catch (PrestoException e) {
    if (isMetastoreRpcError(e)) {
        throw new RetriableException("Metastore RPC failed reading primary key; retrying", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getPrimaryKey (e.g. via connector metadata listing of table constraints) while the metastore RPC throws TException — connection drop, thrift protocol mismatch, NoSuchObject-like server errors, or serialization problems.

Common situations: Metastore restarted mid-query; older Hive metastore version lacking the primary-key API (get_primary_keys); network interruption between coordinator and metastore; thrift timeout under load.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/d9c395f990b20a78. Report an issue: GitHub.