Appearance
Are you an LLM? You can read better optimized documentation at /troubleshooting/contentful_issues.md for this page in Markdown format
Contentful connectivity issues
This document provides a technical guide for diagnosing and resolving connectivity and data retrieval issues related to the Contentful headless CMS in TheExampleApp. It is intended for developers responsible for maintaining the application.
API connection problems
API connection failures are typically the first line of issues encountered. The connection to Contentful is managed through the contentful.aspnetcore SDK, which is configured during application startup. Understanding this configuration flow is key to debugging.
The core of the connection logic revolves around the ContentfulOptions class, which holds the credentials and settings required to communicate with the Contentful API. These settings are initially loaded from appsettings.json.
However, a key architectural feature of this application is the ability to override these settings at runtime for the current user's session. This is handled by the ContentfulOptionsManager.
csharp
// File: TheExampleApp/Configuration/ContentfulOptionsManager.cs
/// <summary>
/// Gets the currently configured <see cref="ContentfulOptions"/> either from session, if present, or from the application configuration.
/// </summary>
public ContentfulOptions Options {
get {
var sessionString = _accessor.HttpContext.Session.GetString(nameof(ContentfulOptions));
if (!string.IsNullOrEmpty(sessionString))
{
// If options are found in the session, deserialize and use them.
return JsonConvert.DeserializeObject<ContentfulOptions>(sessionString);
}
// Otherwise, fall back to the default options from appsettings.json.
return _options;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Gotcha: When debugging, always consider that a user's session might contain different credentials than those specified in appsettings.json. The /settings page of the application allows users to input and test their own credentials, which are then stored in the session. The IsUsingCustomCredentials property on the ContentfulOptionsManager can be used to verify if a session override is active.
Authentication errors
Authentication errors occur when the application provides invalid credentials to the Contentful API. The most common causes are an incorrect Space ID, Delivery API Key, or Preview API Key.
The application's default credentials are set in appsettings.json:
json
// File: TheExampleApp/appsettings.json
{
"ContentfulOptions": {
"DeliveryApiKey": "df2a18b8a5b4426741408fc95fa4331c7388d502318c44a5b22b167c3c1b1d03",
"PreviewApiKey": "10145c6d864960fdca694014ae5e7bdaa7de514a1b5d7fd8bd24027f90c49bbc",
"SpaceId": "qz0n5cdakyl9",
"UsePreviewApi": false
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
For more details on the initial setup, refer to the Contentful Setup and API Configuration documentation.
The application proactively validates credentials submitted via the /settings page. The Validate method within the SelectedOptions class in Settings.cshtml.cs attempts to make a GetSpace() call to both the Delivery and Preview APIs. This logic provides an excellent template for diagnosing authentication issues.
csharp
// File: TheExampleApp/Pages/Settings.cshtml.cs
private IEnumerable<ValidationResult> MakeTestCalls(HttpClient httpClient, IContentfulClient contentfulClient, IViewLocalizer localizer)
{
ValidationResult validationResult = null;
try
{
// Test call to the Delivery API
var space = contentfulClient.GetSpace().Result;
}
catch (AggregateException ae)
{
ae.Handle((ce) => {
if (ce is ContentfulException)
{
// A 401 status code indicates an invalid or revoked API key.
if ((ce as ContentfulException).StatusCode == 401)
{
validationResult = new ValidationResult(localizer["deliveryKeyInvalidLabel"].Value, new[] { nameof(AccessToken) });
}
// A 404 status code often means the Space ID is incorrect.
else if ((ce as ContentfulException).StatusCode == 404)
{
validationResult = new ValidationResult(localizer["spaceOrTokenInvalid"].Value, new[] { nameof(SpaceId) });
}
else
{
validationResult = new ValidationResult($"{localizer["somethingWentWrongLabel"].Value}: {ce.Message}", new[] { nameof(AccessToken) });
}
return true;
}
return false;
});
}
// ... similar logic is repeated for the Preview API ...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Debugging Steps:
- Verify that the
SpaceId,DeliveryApiKey, andPreviewApiKeyinappsettings.jsonare correct for your Contentful space. - If the issue is user-specific, check if they have entered custom credentials on the
/settingspage, which would be stored in their session. - When an API call fails, catch the
ContentfulExceptionand inspect itsStatusCodeproperty:- 401 (Unauthorized): The API key (
DeliveryApiKeyorPreviewApiKey) is invalid or has been revoked. - 404 (Not Found): The
SpaceIdis likely incorrect, or the resource you are requesting does not exist.
- 401 (Unauthorized): The API key (
Content not displaying
If the API connection is successful but content is missing, the issue often lies with locale settings or the distinction between the Preview and Delivery APIs.
Locale Mismatches
The application supports multiple locales (en-US and de-DE), and the content served by Contentful is locale-specific. The locale resolution logic is complex and can be a source of issues.
In Startup.cs, a CustomRequestCultureProvider is configured to determine the correct locale for a request.
- It first checks for a
localeparameter in the query string (e.g.,?locale=de-DE). - It verifies that this locale exists within the Contentful space.
- If the locale exists in Contentful but is not officially supported by the application (i.e., not in the
SupportedCultureslist), it traverses the fallback chain defined in Contentful to find a supported locale. - The resolved locale and a potential fallback are stored in the session using the keys
localeandfallback-locale.
Gotcha: If you request a locale that is not supported by the application and has no supported fallback in its chain, the application will revert to the default culture (en-US). This can lead to content appearing in the wrong language or not at all if an entry hasn't been localized for the default language.
Preview vs. Delivery API
A common reason for "missing" content is requesting an entry that has not yet been published.
- Delivery API: Returns only content that has been explicitly published. This is the default API used by the application.
- Preview API: Returns all content, including drafts and entries with pending changes.
The API in use is determined by the UsePreviewApi boolean in the ContentfulOptions. This can be toggled via the /settings page, which updates the session configuration. If a content editor creates a new entry but doesn't publish it, developers must use the Preview API to see it in the application.
Rate limiting
Contentful APIs enforce rate limits to ensure service stability. The contentful.aspnetcore SDK has built-in support for handling rate-limiting by automatically retrying failed requests. This behavior is configured via the MaxNumberOfRateLimitRetries property in ContentfulOptions.
While the SDK handles transient rate limit errors, sustained high traffic can still exhaust the retries and lead to ContentfulExceptions with a status code of 429 (Too Many Requests).
If you encounter frequent rate-limiting issues:
- Review your code for inefficient API calls (e.g., fetching entries inside a loop).
- Implement caching strategies to reduce the number of requests to Contentful.
- Consider upgrading your Contentful plan for higher rate limits if necessary.
Debugging API calls
Effective debugging requires visibility into the API requests being made and the responses being received.
Logging Contentful Requests
The application uses the standard ASP.NET Core logging framework. To get detailed information about Contentful API calls, you can increase the log verbosity. In your appsettings.Development.json, lower the default log level for the Contentful SDK and related components:
json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Warning",
"Microsoft": "Warning",
"Contentful": "Debug" // Set to Debug for maximum detail from the SDK
}
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
This will output detailed information about requests, responses, and any automatic retries for rate limiting to your console or configured logging provider. For more general debugging tips, see the Debugging Guide.
Inspecting Responses
The validation logic in Settings.cshtml.cs provides a robust pattern for actively probing the API and handling exceptions. You can adapt this pattern when building new features or debugging existing ones. Wrap your IContentfulClient calls in a try-catch block to inspect the full ContentfulException object, which contains the status code, response body, and a unique RequestId that can be shared with Contentful support.
For further assistance, consult the Common Issues page.