URL Encoded Asterisk (%2A): Can an Asterisk Be in a URL?
The asterisk sits in an awkward corner of the URL specifications: it is a sub-delimiter, most tools leave it alone, and a handful of APIs insist it be encoded. Knowing which situation you are in decides whether it matters.
The specification
RFC 3986 lists * as a sub-delimiter, which means reserved — it should be percent-encoded as %2A when it appears as data rather than as a delimiter.
In practice no server treats * structurally in a query string, so an unencoded asterisk passes through untouched. That is why almost nothing encodes it.
What the tools do
encodeURIComponent leaves * alone, along with !, ', ( and ). These five are the well-known gap between the JavaScript function and strict RFC 3986:
encodeURIComponent("a*b!c'd(e)"); // "a*b!c'd(e)" — unchanged
// strict RFC 3986
const strict = (s) => encodeURIComponent(s).replace(
/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase()
);
PHP's rawurlencode encodes * as %2A, and so does Python's quote, whose always-safe set is only letters, digits and _.-~. JavaScript is the odd one out, so a value encoded in the browser and again on a Python or PHP server can differ by exactly these characters.
When it actually matters
Request signing. AWS Signature v4, OAuth 1.0a and similar schemes build a canonical string from the encoded URL, so client and server must encode identically. A * encoded on one side and not the other produces a signature mismatch with a completely unhelpful error message.
It is a frequent cause of "signature does not match" when the request otherwise looks correct, and it applies to !, ', ( and ) too. Read what the API documents and match it exactly rather than trusting your language default.
Outside signing, leave it. An unencoded asterisk in a normal query string is fine everywhere.
Frequently asked questions
Does * need to be URL encoded?
Strictly yes, as %2A. In practice it passes through unencoded except where a signature requires canonical encoding.
Why does encodeURIComponent skip it?
It follows an older specification that treated ! ' ( ) * as safe. RFC 3986 disagrees.
My API signature keeps failing — could this be why?
Yes. Mismatched encoding of ! ' ( ) * between client and server is a frequent cause.