Auth0 MAX_ARRAY_VALUES_PER_KEY Limit: Why Arrays Are Capped at 20 Values in auth0-auth-js
The MAX_ARRAY_VALUES_PER_KEY constant in the auth0-auth-js SDK restricts the extras parameter to 20 array values per key, protecting Auth0's token endpoint from denial-of-service attacks while maintaining predictable request payloads.
The auth0-auth-js repository provides JavaScript SDKs for Auth0 authentication flows, including the AuthClient class that handles OAuth token exchanges. When developers pass additional parameters through the extras option in methods like exchangeTokenByCode(), the SDK enforces strict validation on array contents. This article examines the implementation details in the source code, explains the security rationale behind the 20-item ceiling, and demonstrates compliant patterns for handling larger datasets.
What is the MAX_ARRAY_VALUES_PER_KEY Limit?
In packages/auth0-auth-js/src/auth-client.ts at line 65, the SDK defines a hardcoded constant:
const MAX_ARRAY_VALUES_PER_KEY = 20;
This value governs how the appendExtraParams method processes the extras object passed to token-exchange methods. When a key in extras contains an array, the SDK iterates through the values and validates the length against this constant. If the array exceeds 20 items, the SDK throws a TokenExchangeError (defined in packages/auth0-auth-js/src/errors.ts) at lines 151-154 of auth-client.ts, halting the request before it reaches Auth0's servers.
The limit specifically targets the token exchange flow where array values serialize into individual key-value pairs in the URL-encoded form body. Each item becomes a separate field in the HTTP POST request to the /oauth/token endpoint, making the cap essential for controlling payload expansion.
Why the 20-Item Limit Exists in auth0-auth-js
The auth0-auth-js development team implemented this restriction for three specific technical reasons documented in the source code comments:
DoS Protection
Unbounded arrays could enable denial-of-service attacks. A malicious actor could pass an array containing thousands of items, generating an HTTP request large enough to exhaust memory on both the client browser and the Auth0 authentication endpoint. By capping arrays at 20 values per key, the SDK prevents arbitrarily large payloads that could degrade service availability.
Predictable Request Size
Auth0's token endpoint expects modest, well-defined request bodies typical of URL-encoded form submissions. The 20-item limit aligns with the service's internal validation logic and prevents edge cases where oversized requests might trigger rejections by intermediate proxies, load balancers, or server-side request size validators.
API Contract Simplicity
The extras parameter accepts "untyped" key-value pairs to accommodate various OAuth extensions and custom parameters. Allowing unlimited arrays would require complex validation logic, pagination handling, and extensive documentation about chunking strategies. The fixed limit encourages developers to aggregate data into structured strings or split operations across multiple calls, resulting in cleaner, more intentional API designs.
How the Limit is Enforced in the Source Code
The validation logic resides in the appendExtraParams private method within auth-client.ts. When processing the extras object during token exchange preparation, the SDK performs this check:
// Validation logic from auth-client.ts lines 65 and 151-154
if (Array.isArray(value) && value.length > MAX_ARRAY_VALUES_PER_KEY) {
throw new TokenExchangeError(
`Parameter '${key}' exceeds maximum array size of ${MAX_ARRAY_VALUES_PER_KEY}`
);
}
This validation occurs synchronously before the HTTP client dispatches the request. The TokenExchangeError class provides a clear, actionable message indicating which parameter violated the constraint, allowing developers to identify oversized arrays immediately during development.
Working with the Array Limit: Code Examples
The following patterns demonstrate compliant usage, error conditions, and recommended workarounds for handling data sets that exceed 20 items.
Valid Usage Within the Limit
This example passes two resource URLs in the extras parameter, well under the maximum threshold:
import { AuthClient } from '@auth0/auth0-auth-js';
const client = new AuthClient({
domain: 'tenant.auth0.com',
clientId: 'your-client-id'
});
await client.exchangeTokenByCode({
code: 'splkJH2...',
redirect_uri: 'https://myapp.com/callback',
extras: {
resource: [
'https://api.example.com/read',
'https://api.example.com/write'
]
}
});
The SDK serializes each array item as a separate resource field in the form-encoded request body sent to the token endpoint.
Error When Exceeding the Limit
Attempting to pass 21 items triggers the validation error immediately:
await client.exchangeTokenByCode({
code: 'splkJH2...',
redirect_uri: 'https://myapp.com/callback',
extras: {
resource: Array.from({ length: 21 }, (_, i) =>
`https://api.example.com/resource${i}`
)
}
});
This code throws the following exception before network transmission:
TokenExchangeError: Parameter 'resource' exceeds maximum array size of 20
Workaround Using JSON Aggregation
To send larger datasets, aggregate values into a single JSON string that counts as one parameter value:
const resources = Array.from({ length: 50 }, (_, i) =>
`https://api.example.com/resource${i}`
);
await client.exchangeTokenByCode({
code: 'splkJH2...',
redirect_uri: 'https://myapp.com/callback',
extras: {
resources_json: JSON.stringify(resources)
}
});
The receiving server parses resources_json to access all 50 values while the SDK remains compliant with the MAX_ARRAY_VALUES_PER_KEY constraint.
Summary
- The
MAX_ARRAY_VALUES_PER_KEYconstant inauth-client.tsenforces a hard limit of 20 array items per key in theextrasparameter. - This restriction prevents DoS attacks via oversized payloads, maintains predictable HTTP request sizes for Auth0's token endpoint, and simplifies the SDK's API contract.
- Exceeding the limit triggers a
TokenExchangeErrorduring parameter validation at lines 151-154 ofauth-client.ts, before the HTTP request is dispatched. - Developers can work around the restriction by aggregating data into JSON strings, splitting requests across multiple token exchanges, or redesigning data structures to avoid large parameter arrays.
Frequently Asked Questions
Can I configure or increase the MAX_ARRAY_VALUES_PER_KEY limit in auth0-auth-js?
No, the limit is currently non-configurable. The constant is hardcoded in packages/auth0-auth-js/src/auth-client.ts and requires modification of the SDK source code itself to change. According to the source code comments, the recommended approach is to aggregate data using JSON.stringify() rather than attempting to raise the ceiling.
What error does auth0-auth-js throw when the array limit is exceeded?
The SDK throws a TokenExchangeError with the message format: Parameter '{key}' exceeds maximum array size of 20. This error originates from the validation logic at lines 151-154 of auth-client.ts during the parameter processing phase, preventing the oversized request from reaching Auth0's authentication servers.
Which Auth0 SDK methods enforce the MAX_ARRAY_VALUES_PER_KEY limit?
The limit applies to any method utilizing the internal appendExtraParams utility, primarily exchangeTokenByCode(). Any token exchange operation accepting the extras option parameter undergoes this validation, as implemented in the core AuthClient class in packages/auth0-auth-js/src/auth-client.ts.
How can I send more than 20 values to Auth0 if my application requires them?
The SDK documentation suggests three approaches: aggregate the data into a single structured value using JSON.stringify(), split the operation across multiple token exchange calls, or redesign the API to avoid passing large datasets as OAuth parameters. These patterns comply with the security model while accommodating complex data requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →