prestodb/presto · error · IllegalArgumentException

Access control '%s' is already registered

Error message

Access control '%s' is already registered

What it means

AccessControlManager.addSystemAccessControlFactory registers SystemAccessControlFactory instances by name in a map using putIfAbsent. If a factory with the same getName() is already registered, it throws IllegalArgumentException — the manager never allows two system access control plugins under one name.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/security/AccessControlManager.java:108

    private final CounterStat authorizationFail = new CounterStat();
    private StatsRecordingSystemAccessControl.Stats detailedStats = new StatsRecordingSystemAccessControl.Stats();

    @Inject
    public AccessControlManager(TransactionManager transactionManager)
    {
        this.transactionManager = requireNonNull(transactionManager, "transactionManager is null");
        addSystemAccessControlFactory(new AllowAllSystemAccessControl.Factory());
        addSystemAccessControlFactory(new ReadOnlySystemAccessControl.Factory());
        addSystemAccessControlFactory(new FileBasedSystemAccessControl.Factory());
        addSystemAccessControlFactory(new DenyQueryIntegrityCheckSystemAccessControl.Factory());
    }

    public void addSystemAccessControlFactory(SystemAccessControlFactory accessControlFactory)
    {
        requireNonNull(accessControlFactory, "accessControlFactory is null");

        if (systemAccessControlFactories.putIfAbsent(accessControlFactory.getName(), accessControlFactory) != null) {
            throw new IllegalArgumentException(format("Access control '%s' is already registered", accessControlFactory.getName()));
        }
    }

    public void addCatalogAccessControl(ConnectorId connectorId, ConnectorAccessControl accessControl)
    {
        requireNonNull(connectorId, "connectorId is null");
        requireNonNull(accessControl, "accessControl is null");
        checkState(connectorAccessControl.putIfAbsent(connectorId, new CatalogAccessControlEntry(connectorId, accessControl)) == null,
                "Access control for connector '%s' is already registered", connectorId);
    }

    public void removeCatalogAccessControl(ConnectorId connectorId)
    {
        connectorAccessControl.remove(connectorId);
    }

    public void loadSystemAccessControl()
            throws Exception

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Remove duplicate plugin jars so only one provider of that system access control name is installed
  2. Check the factory's getName() for accidental duplicates
  3. In tests, create a fresh AccessControlManager or use distinct factory names per registration
  4. Wrap registration to skip factories already present if idempotent startup is intended

Example fix

// before
accessControlManager.addSystemAccessControlFactory(factory);
// after
if (accessControlManager.getSystemAccessControlFactories().stream()
        .noneMatch(f -> f.getName().equals(factory.getName()))) {
    accessControlManager.addSystemAccessControlFactory(factory);
}
Defensive patterns

Strategy: validation

Validate before calling

boolean alreadyRegistered = manager.getSystemAccessControlFactories().stream()
    .anyMatch(f -> f.getName().equals(factory.getName()));
if (alreadyRegistered) { skip-or-log; }

Type guard

boolean isRegisterable(SystemAccessControlFactory f, Set<String> registeredNames) {
    return f.getName() != null && !registeredNames.contains(f.getName());
}

Try / catch

try {
    manager.addSystemAccessControlFactory(factory);
} catch (IllegalArgumentException e) {
    log.warn("System access control factory already registered: {}", factory.getName());
}

Prevention

When it happens

Trigger: Calling addSystemAccessControlFactory with a factory whose name collides with an already-registered factory; most commonly a plugin jar loaded twice, the same plugin installed in multiple plugin directories, or a test calling the method twice for the same factory.

Common situations: Duplicate plugin deployment (same plugin in plugins/ twice or an old and new jar both providing the same access control name); re-registration after a failed bootstrap retried in-process; test setup that adds the factory on every test without resetting the manager.

Related errors


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