twigphp/Twig · error · SecurityNotAllowedFunctionError

Function " " is not allowed.

Error message

Function "%s" is not allowed.

What it means

checkSecurity() throws SecurityNotAllowedFunctionError when the template calls a Twig function not in allowedFunctions. With strict mode disabled, 'parent', 'block', and 'attribute' are temporarily permitted via deprecation notices (removed in 4.0); all other unlisted functions throw.

Solutions

  1. Add the function to the allowlist via the constructor or $policy->setAllowedFunctions([...]).
  2. Explicitly allow 'parent', 'block', 'attribute' if you rely on the pre-4.0 behavior, and enable strict mode to test 4.0 behavior early.
  3. Catch SecurityNotAllowedFunctionError to report the blocked function name.
  4. Wrap function usage in custom whitelisted Twig functions if fine-grained control is needed.

Example fix

// before
 $policy = new SecurityPolicy([], [], [], [], []); // template calls range()
// after
 $policy = new SecurityPolicy([], [], [], ['range', 'parent', 'block', 'attribute'], []);
 $policy->setStrict(true);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!in_array($fn, $allowedFunctions, true)) {
    throw new \LogicException("Function '$fn' not allowed by sandbox policy");
}

Try / catch

try {
    $html = $twig->render($tpl, $ctx);
} catch (\Twig\Sandbox\SecurityNotAllowedFunctionError $e) {
    $logger->warning('Sandbox blocked function', ['function' => $e->getFunctionName()]);
}

Prevention

When it happens

Trigger: A sandboxed template calls a function absent from the $functions constructor argument / setAllowedFunctions(); relying on 'parent'/'block'/'attribute' without strict mode (works now, throws in 4.0); a strict-mode policy rejecting any unlisted function.

Common situations: Migrating toward Twig 4.0 sandbox semantics; a template gaining a new function call after the policy was written; macro/namespace tests exercising sandbox exemptions.

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 twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/57ae9d260fde25a8. Report an issue: GitHub.

Appendix: source

Thrown at src/Sandbox/SecurityPolicy.php:131

            }
        }

        foreach ($filters as $filter) {
            if (!\in_array($filter, $this->allowedFilters, true)) {
                throw new SecurityNotAllowedFilterError(\sprintf('Filter "%s" is not allowed.', $filter), $filter);
            }
        }

        foreach ($functions as $function) {
            if (!\in_array($function, $this->allowedFunctions, true)) {
                if (!$this->strict && 'parent' === $function) {
                    trigger_deprecation('twig/twig', '3.27', 'The "parent" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
                } elseif (!$this->strict && 'block' === $function) {
                    trigger_deprecation('twig/twig', '3.27', 'The "block" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
                } elseif (!$this->strict && 'attribute' === $function) {
                    trigger_deprecation('twig/twig', '3.27', 'The "attribute" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
                } else {
                    throw new SecurityNotAllowedFunctionError(\sprintf('Function "%s" is not allowed.', $function), $function);
                }
            }
        }

        foreach ($tests as $test) {
            if (!\in_array($test, $this->allowedTests, true)) {
                if (!$this->strict) {
                    trigger_deprecation('twig/twig', '3.28', 'The "%s" test is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).', $test);
                } else {
                    throw new SecurityNotAllowedTestError(\sprintf('Test "%s" is not allowed.', $test), $test);
                }
            }
        }
    }

    public function checkMethodAllowed($obj, $method): void
    {
        if ($obj instanceof Template || $obj instanceof Markup) {

View on GitHub (pinned to a414c3a491)