Fix the Invalid Character ‘<' Error When Parsing JSON

The error invalid character '<' looking for beginning of value means a JSON parser encountered < where it expected a JSON value, usually because it received HTML instead of JSON. The underlying problem is often a wrong API endpoint, a login redirect, or an error page from a server or proxy. Match the response to the symptoms below, then inspect the actual input before changing your code or credentials.

What You Find Likely Cause What to Fix
HTML containing “Not Found,” often with HTTP 404 Wrong hostname, route, or API version Correct the full API URL
A login page or redirect to a sign-in URL Missing authentication or a browser-only authentication flow Use the API’s supported authentication method
An HTML access-denied or security-challenge page Permissions, firewall, proxy, or gateway rejection Identify which service rejected the request and correct its access configuration
An HTML maintenance or gateway-error page Unavailable service or failed upstream connection Restore the service or upstream connection before retrying
HTTP 200 OK, but the body is a website Request reached a web interface or frontend fallback route Route the request to the API rather than the website
A local “JSON” file beginning with HTML or XML Wrong file, failed download, or incorrect parser Restore the intended JSON file or use the parser for the actual format

What the JSON Parsing Error Means

Inspect the raw input and its delivery mode before editing JSON or changing credentials: < can indicate HTML, while : can indicate an SSE comment.

This error wording commonly comes from Go’s JSON decoder, including applications and command-line tools written in Go. You do not need to be writing Go yourself to encounter it.

For example, an application might expect:

{"status":"ok"}

Instead, the application might receive an HTML sign-in page:

<!DOCTYPE html>
<html>
  <body>Please sign in</body>
</html>

The JSON decoder cannot interpret that opening < as the beginning of a JSON value. Its error describes the parsing failure, not why the server sent the wrong content.

“Beginning of value” also does not necessarily mean the first byte of the entire document. A parser can encounter an invalid character where a nested value should begin. Inspecting the actual input distinguishes a completely wrong response format from damaged JSON.

Two details help avoid false diagnoses:

  • < is legal inside a quoted JSON string, such as {"markup":"<p>Hello</p>"}.
  • HTML is the common explanation, not the only one. XML, debug output, and accidentally combined responses can also introduce < where JSON is expected.

How to Fix the Invalid Character Error

Identify the actual response or file reaching the decoder, inspect its contents, and correct the confirmed source of unexpected content.

Step 1: Identify What the Application Is Trying to Decode

  1. Find the operation immediately before the error: an API request, model download, provider initialization, configuration load, or streamed response.
  2. Determine whether the input comes from an HTTP response or a local file.
  3. Record the active endpoint or file path, the application version, and any relevant environment overrides.

For an HTTP request, capture the complete constructed URL, not just the configured base URL. A client can append an incorrect route or duplicate an API-version segment even when its base address looks right.

For a file, confirm that the application is opening the file you are inspecting. Working directories, mounted volumes, and environment variables can cause a service to load a different configuration than the one you edited.

Do not clear caches or reinstall the tool yet. Neither action establishes what reached the decoder.

Step 2: Inspect the Response Before Parsing It

  1. Examine the HTTP status, response headers, redirect behavior, and beginning of the body.
  2. Reproduce the request from the environment where it fails, preserving its method, authentication, and request body.
  3. Identify whether the content came from the intended API, a website, or an intermediary.

For a simple GET request, replace the placeholder URL and run:

curl --silent --show-error --include 'https://api.example.com/your-endpoint'

This displays the response headers followed by the body. It does not automatically follow redirects, so an initial redirect remains visible.

For authenticated or more complex requests, use your API request client or the application’s supported diagnostics to preserve the original request. An unauthenticated GET is not a faithful reproduction of an authenticated POST. Avoid replaying state-changing production requests solely to inspect their responses; use an existing capture or a safe test operation.

Look for:

  • Status: Did the server return success, rejection, a redirect, or a server error?
  • Content-Type: Does the response advertise JSON, HTML, XML, or a streaming format?
  • Location: Is a redirect sending the client to a login page or another host?
  • Body: Does it contain a recognizable login form, gateway message, website, or API error?
  • Final URL: Did the application follow a redirect before attempting to decode the response?

A Go HTTP client commonly follows redirects automatically. That can turn an initial authentication redirect into a final HTML page with a successful HTTP status.

Run this check from the failing container or service environment when possible. A successful browser request on your laptop does not establish that a container uses the same DNS, proxy, credentials, or network route.

Keep diagnostic output private. Headers and bodies can contain tokens, cookies, account information, and signed URLs; redact them before sharing.

Step 3: Repair the Source of the Unexpected Content

  1. Correct request configuration when the destination is wrong. Check the scheme, hostname, port, region, and complete route. Distinguish the product’s web interface from its API address, and verify that the client supports the operation on that service.
  2. Correct authentication only when the response indicates an access problem. Confirm that credentials are actually populated in the running process and sent using the expected mechanism. A token stored in a local configuration file does not prove that a container or background service loaded it.
  3. Correct the intermediary when it generated the page. Identify the proxy, gateway, ingress, or access-control service responsible. Repair its routing, upstream connection, or approved access policy rather than disabling certificate verification.
  4. Repair local input when no HTTP request is involved. If a supposed JSON file contains an HTML download-error page, preserve the original for diagnosis and replace it with the intended JSON content. Validate the replacement before loading it.

Do not hard-code secrets into source files to make an authentication problem disappear. Fix the application’s supported credential-loading mechanism.

Request headers also have different jobs. Accept: application/json expresses a preference for a JSON response; the request’s Content-Type describes the body you are sending. Neither forces a server or proxy to return JSON, and relabeling an HTML response as JSON does not make it parseable.

Step 4: Repeat the Original Operation

  1. Repeat the operation with the corrected configuration, using the same runtime environment.
  2. Confirm that the response contains the expected data, not merely that the parsing error disappeared.
  3. Verify that the original task finishes: the API result loads, the configuration is accepted, the provider initializes, or the download proceeds.

If the response is now valid JSON but the application reports a different error, handle that new error separately. A JSON authentication error, missing field, or type mismatch means you have progressed beyond the original format mismatch.

How to Handle JSON Responses in Go

A common programming mistake is decoding every response body without checking what the server returned.

In Go, a nil error from an HTTP request means the client obtained a response; it does not mean the HTTP status represents success. A server can return an HTML error page without causing the HTTP request function itself to fail.

For a non-streaming endpoint that promises one JSON document, this helper checks the status and media type before decoding. It also rejects extra content after the JSON document:

package apiclient

import (
	"encoding/json"
	"fmt"
	"io"
	"mime"
	"net/http"
	"strings"
)

func DecodeJSONResponse(resp *http.Response, dst any) error {
	defer resp.Body.Close()

	if resp.StatusCode < http.StatusOK ||
		resp.StatusCode >= http.StatusMultipleChoices {
		return fmt.Errorf(
			"unexpected HTTP status %s; Content-Type %q",
			resp.Status,
			resp.Header.Get("Content-Type"),
		)
	}

	contentType := resp.Header.Get("Content-Type")
	mediaType, _, err := mime.ParseMediaType(contentType)
	isJSON := mediaType == "application/json" ||
		(strings.HasPrefix(mediaType, "application/") &&
			strings.HasSuffix(mediaType, "+json"))

	if err != nil || !isJSON {
		return fmt.Errorf(
			"expected a JSON response; Content-Type %q",
			contentType,
		)
	}

	decoder := json.NewDecoder(resp.Body)
	if err := decoder.Decode(dst); err != nil {
		return fmt.Errorf("decode response JSON: %w", err)
	}

	var extra any
	if err := decoder.Decode(&extra); err != io.EOF {
		if err == nil {
			return fmt.Errorf("unexpected extra JSON value")
		}
		return fmt.Errorf("unexpected data after JSON: %w", err)
	}

	return nil
}

Use this after the HTTP request succeeds at the transport level, passing a pointer to the destination value. The helper consumes and closes the response body.

This is deliberately strict about the response format:

  • It accepts application/json and application media types ending in +json.
  • It handles media-type parameters through mime.ParseMediaType.
  • It does not assume that a JSON header guarantees a valid JSON body.
  • It expects a body containing one JSON document, not an empty response or an indefinite stream.

Handle documented bodyless responses separately. If an endpoint serves JSON with an incorrect or missing media type, correct the server or make an explicit, endpoint-specific exception rather than accepting any response blindly.

After integrating the helper, test both the normal JSON response and an error response. The normal operation should still succeed, while an HTML response should produce a useful status or media-type error instead of an unexplained decoder failure.

Special Cases in Tools and Streaming APIs

Tool downloads and streaming APIs require verification of their actual responses and delivery formats before parsing or changing local data.

Cloud CLIs and Terraform Providers

A valid connection configuration does not guarantee that every command is supported by the destination service. For example, the ping operation is unavailable for InfluxDB Cloud under the InfluxDB Cloud CLI documentation. Use a supported Cloud operation to verify access rather than treating a ping failure as proof that the token is invalid.

For Terraform, an error attributed to a provider block can originate in the provider’s HTTP request rather than in HCL syntax. Inspect the resolved API host and whether the running provider received its credentials, especially when values come from environment variables or another data source.

Use supported secret injection instead of copying credentials into configuration files. Once the endpoint and credential loading are corrected, rerun the intended validation or plan and confirm that provider initialization completes. Updating an old client may improve its error messages, but it does not repair an incorrect destination.

Model Pulls and Package Downloads

When Ollama displays:

Error: pull model manifest: invalid character '<' looking for beginning of value

the failed operation is parsing manifest-related content. It does not, by itself, establish that an existing local model is corrupt.

Inspect the response and network path used by the running Ollama server, not only the shell that invoked the client. A registry request can encounter a login page, filtering proxy, or gateway error before any model data is downloaded.

Correct the confirmed registry, access, or network problem, then repeat the original pull and verify that manifest retrieval and downloading proceed. Deleting existing models is not a justified first response to this parsing error.

Similarly, when yay fails during its AUR update search, investigate the AUR metadata response and active configuration before modifying local package databases. After correcting the failing connection or service condition, repeat the update check and confirm that the AUR search completes.

Streaming and SSE Responses

Streaming APIs need a parser for their delivery format. A server-sent events response can contain keep-alive comments beginning with : keep-alive, which are not JSON values:

: keep-alive

data: {"message":"hello"}

Sending every line directly to a JSON decoder can therefore produce:

invalid character ':' looking for beginning of value

Use an SSE-aware handler that:

  1. Ignores SSE comment lines.
  2. Collects data fields into complete events.
  3. Decodes an event’s payload as JSON only when the API defines it as JSON.
  4. Handles the API’s documented completion markers separately.

Do not indiscriminately remove colons from the response. Colons are meaningful in both SSE framing and JSON.

After changing the handler, run a stream long enough to receive a keep-alive and a subsequent data event. Confirm that the connection remains open and the following event is delivered correctly. An SSE stream, newline-delimited JSON stream, and ordinary JSON document require different handling even when they carry similar data.

How to Confirm the Fix and Prevent Recurrence

The repair is complete when the original operation works in its original environment. Use this final check:

  • The request reaches the intended service without an unexpected redirect.
  • The response status and format match the endpoint’s contract.
  • The application receives the expected fields or events.
  • Failure responses produce an actionable error instead of being blindly decoded.

If you control the server, make API error responses consistent with the API’s documented format. Authentication middleware, reverse proxies, and frontend fallback routes can return HTML even when the application normally returns JSON.

If you control the client, preserve enough context to distinguish a transport failure, HTTP rejection, format mismatch, and JSON syntax error. Record the status, media type, and a sanitized destination; avoid unrestricted logging of response bodies or credential-bearing URLs.

Add a regression test for the failure you found, such as a login redirect, HTML gateway response, or SSE keep-alive, then rerun the original operation before closing the issue.

Frequently Asked Questions

Why Does config.json Report an Invalid Character '/'?

A slash where a JSON value should begin often indicates a comment, because standard JSON does not allow // or /* ... */ comments. Remove comment syntax outside strings, but preserve legitimate slashes inside strings, such as URLs. Validate the file as JSON, save it, and reload the application.

What Does Invalid Character 's' Looking for Beginning of Value Mean?

An invalid character ‘s’ error means the parser encountered an unquoted s where it expected a JSON value. The input might be plain text such as service unavailable, but the character alone does not identify the message or its cause. Inspect the raw content, correct the response source or file format, and repeat the operation.

What Does “Error Unmarshalling Content” Mean?

“Unmarshalling” means converting serialized data into values the program can use, such as structures, maps, or lists. When that message includes invalid character '<', the conversion failed because the input was not valid JSON at that position. It does not necessarily indicate a problem with your destination structure; establish that the input is JSON first.

Why Does a “PV 1 Power” Reading Show This Error?

The label identifies the reading that failed to load; the JSON error alone does not establish a fault in the power hardware. If the reading comes from a device or monitoring-service integration, inspect that integration’s response for an authentication page, incorrect endpoint, or service error. Correct the confirmed communication problem, then refresh the reading and verify that actual measurement data returns.