apple/pkl · error · SecurityManagerException

insufficientModuleTrustLevel

insufficientModuleTrustLevel

Error message

insufficientModuleTrustLevel

What it means

Pkl's module security manager enforces per-module trust levels. When an importing module has a strictly lower trust level than the module it tries to import, checkImportModule throws a SecurityManagerException with error code `insufficientModuleTrustLevel`, blocking the import at evaluation time.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/SecurityManagers.java:171

    public void checkResolveResource(URI resource) throws SecurityManagerException {
      checkRead(resource, allowedResources, true);
    }

    @Override
    public void checkReadResource(URI uri) throws SecurityManagerException {
      checkRead(uri, allowedResources, true);
    }

    @Override
    public void checkImportModule(URI importingModule, URI importedModule)
        throws SecurityManagerException {
      var importingTrustLevel = trustLevels.apply(importingModule);
      var importedTrustLevel = trustLevels.apply(importedModule);

      if (importingTrustLevel < importedTrustLevel) {
        var message =
            ErrorMessages.create("insufficientModuleTrustLevel", importedModule, importingModule);
        throw new SecurityManagerException(message);
      }
    }

    @Override
    public @Nullable Path resolveSecurePath(URI uri, boolean isResource)
        throws SecurityManagerException, IOException {
      if (rootDir == null
          || !uri.isAbsolute()
          || !uri.getScheme().equals("file")
          || (uri.getAuthority() != null && !uri.getAuthority().isEmpty())) {
        return null;
      }
      var path = Path.of(uri);
      var realPath = path.toRealPath();
      if (!realPath.startsWith(rootDir)) {
        var errorMessageKey = isResource ? "resourcePastRootDir" : "modulePastRootDir";
        var message = ErrorMessages.create(errorMessageKey, uri, rootDir);
        throw new SecurityManagerException(message);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Raise the trust level of the importing module (e.g. run within a trusted project/module context)
  2. Lower the trust requirement of the imported dependency (vendor it locally, use a less-trusted origin consistent with policy)
  3. Adjust the security manager policy/trust mapping so the import is allowed
Defensive patterns

Strategy: try-catch

Validate before calling

// compare trust levels before importing, when possible
// ensure importingModuleTrustLevel >= importedModuleTrustLevel

Try / catch

try {
  return moduleLoader.load(importedModuleUri);
} catch (SecurityManagerException e) {
  if (e.getMessage().contains("insufficientModuleTrustLevel")) {
    // surface a policy fix hint or load from a permitted origin
  }
  throw e;
}

Prevention

When it happens

Trigger: A module imports (via `import ...` or module loader) another module whose computed trust level (based on its URI/origin, e.g. remote HTTPS vs local path) is higher than the importing module's trust level, under a security manager with module trust checks enabled.

Common situations: A local untrusted module trying to import from a trusted dependency; sandboxed/CLI evaluation where project dependencies come from more-trusted origins; changes to security policies or dependency sources that shift trust levels.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/8583301437d6aa09. Report an issue: GitHub.