Runtime verified Test scripts included

Syntax

Base64Decode(encodedString[, encoding, abortOnFailure])  →  string
1–3 arguments

Parameters

Name Type Required Description
encodedString string Yes Well-formed Base64 to decode; anything else aborts the page
encoding string No Name of the character encoding the decoded bytes are read as; defaults to UTF-8
abortOnFailure number | boolean No Send-time failure flag; accepted in every spelling and without effect on a successful decode

Example

%%[
  VAR @decoded
  SET @decoded = Base64Decode("U0ZNQyBBTVBzY3JpcHQgMjAyNg==")
]%%
%%=v(@decoded)=%%

Renders SFMC AMPscript 2026.

Reading a Base64 value out of a link is the common case, and it is the case that needs guarding, because a visitor can put anything in a query string:

%%[
  VAR @raw, @plain
  SET @raw = RequestParameter("t")
  IF Not Empty(@raw) AND Mod(Length(@raw), 4) == 0 THEN
    SET @plain = Base64Decode(@raw)
  ENDIF
]%%
%%=v(@plain)=%%

A malformed value takes the entire page down rather than returning empty — see below.

Return value

string — the decoded text, read from the decoded bytes using the requested encoding.

There is no closed set of sentinel values to test for. In particular there is no error token: a value that cannot be decoded aborts the page instead of returning one.

Behaviour

The pair round-trips exactly, in both alphabets. Base64Decode(Base64Encode(x)) returned the original string unchanged for a plain ASCII value, and for a value containing é and the returned characters were compared by code point against the input — 99, 97, 102, 233, 8364 in and the same out. Nothing is lost in either direction.

The decoded bytes are read as UTF-8 by default. Decoding a UTF-16 payload without naming its encoding returns text with a NUL between every character, which renders as S F M C A M P s c r i p t 2 0 2 6. Passing UTF-16 for that same payload returns it correctly, so the second argument is a real character-encoding name and not a formality.

The third argument does not change the value. All four spellings — 0, 1, true, false — were accepted and every one returned the identical decoded string. Its documented effect concerns aborting a send, which a CloudPage cannot exercise.

The empty string decodes to the empty string. It is the one malformed-looking input that is accepted rather than rejected.

Malformed Base64 aborts the page

There is no lenient path. Three separate malformed shapes each returned HTTP 422 with nothing rendered at all — not an empty string, not a partial result, not garbage:

Call Result
Base64Decode("not!base64###") HTTP 422, page discarded
Base64Decode("SGVsbG8") HTTP 422, page discarded
Base64Decode("SGVsbG8=====") HTTP 422, page discarded

The middle case is the one that bites: that is the correct payload for Hello with its single = stripped, so a value that merely lost its padding in transit is fatal. Since AMPscript has no try/catch, validate any externally supplied value — at minimum a non-empty check and a length divisible by four — before it reaches this function.

Show test script
%%[
  VAR @b, @a, @nb, @e8, @e16
  SET @b = RequestParameter("b")
  SET @a = "SFMC AMPscript 2026"
  SET @nb = Concat("caf", Char(233), Char(8364))
  SET @e8 = "U0ZNQyBBTVBzY3JpcHQgMjAyNg=="
  SET @e16 = "UwBGAE0AQwAgAEEATQBQAHMAYwByAGkAcAB0ACAAMgAwADIANgA="

  /* known-good control: renders on every request, so a run of HTTP 422s
     can be told apart from a broken deploy */
  OutputLine(Concat("CTRL=[", Base64Decode("TWFu"), "]"))

  /* decoding a fixed literal, plus the round trip in both directions in
     the same render - the non-ASCII one is the interesting case */
  IF @b == "safe" THEN
    OutputLine(Concat("--- safe start ---"))
    OutputLine(Concat("BD=[", Base64Decode(@e8), "]"))
    OutputLine(Concat("RT=[", Base64Decode(Base64Encode(@a)), "]"))
    OutputLine(Concat("NBIN=[", @nb, "]"))
    OutputLine(Concat("RTN=[", Base64Decode(Base64Encode(@nb)), "]"))
    OutputLine(Concat("--- safe done ---"))
  ENDIF

  /* the empty string is the one malformed-looking input that is accepted */
  IF @b == "empty" THEN
    OutputLine(Concat("--- empty start ---"))
    OutputLine(Concat("BDE=[", Base64Decode(""), "]"))
    OutputLine(Concat("--- empty done ---"))
  ENDIF

  /* the second argument names the encoding the decoded bytes are read as;
     omitting it on a UTF-16 payload leaves a NUL between every character */
  IF @b == "enc" THEN
    OutputLine(Concat("--- enc start ---"))
    OutputLine(Concat("BD8=[", Base64Decode(@e8, "UTF-8"), "]"))
    OutputLine(Concat("BD16=[", Base64Decode(@e16, "UTF-16"), "]"))
    OutputLine(Concat("BD16X=[", Base64Decode(@e16), "]"))
    OutputLine(Concat("--- enc done ---"))
  ENDIF

  /* the third argument is a send-time flag; all four spellings are accepted
     and none of them changes a successful decode */
  IF @b == "flag" THEN
    OutputLine(Concat("--- flag start ---"))
    OutputLine(Concat("F1=[", Base64Decode(@e8, "UTF-8", 1), "]"))
    OutputLine(Concat("F0=[", Base64Decode(@e8, "UTF-8", 0), "]"))
    OutputLine(Concat("FT=[", Base64Decode(@e8, "UTF-8", true), "]"))
    OutputLine(Concat("FF=[", Base64Decode(@e8, "UTF-8", false), "]"))
    OutputLine(Concat("--- flag done ---"))
  ENDIF

  /* each of the five branches below aborts the page - fetch alone */
  IF @b == "badchars" THEN
    OutputLine(Concat("--- badchars start ---"))
    OutputLine(Concat("B1=[", Base64Decode("not!base64###"), "]"))
  ENDIF

  IF @b == "badpad" THEN
    OutputLine(Concat("--- badpad start ---"))
    OutputLine(Concat("B2=[", Base64Decode("SGVsbG8"), "]"))
  ENDIF

  IF @b == "overpad" THEN
    OutputLine(Concat("--- overpad start ---"))
    OutputLine(Concat("B3=[", Base64Decode("SGVsbG8====="), "]"))
  ENDIF

  IF @b == "a0" THEN
    OutputLine(Concat("--- a0 start ---"))
    OutputLine(Concat("A0=[", Base64Decode(), "]"))
  ENDIF

  IF @b == "a4" THEN
    OutputLine(Concat("--- a4 start ---"))
    OutputLine(Concat("A4=[", Base64Decode(@e8, "UTF-8", 1, "extra"), "]"))
  ENDIF
]%%

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next No

See also