swisskyrepo/PayloadsAllTheThings · warning · Exception

Value not found: %s

Error message

Value not found: %s

What it means

convert(s, recurse_chunks=True, error_on_miss=False) in ip.py raises Exception('Value not found: %s' % s) only when error_on_miss is True and the string s (after recursive right-to-left splitting down to single characters) still has a bottom-level character absent from EnclosedAlphanumericsData. The table only covers '0'-'9', '10'-'20', '.', 'a'-'f', and 'x', so any other character — letters g-z, uppercase, ':', '-', whitespace — reaches the single-char base case, misses, and (with the flag set) raises. With the default error_on_miss=False the same input is silently returned unchanged, which is the designed fallback behavior.

Source

Thrown at Server Side Request Forgery/Files/ip.py:120

			if x <= 2:
				returnEnclosedAlphanumericsIPAddress = returnEnclosedAlphanumericsIPAddress + plain2EnclosedAlphanumericsChar('.');
		else:
			returnEnclosedAlphanumericsIPAddress = returnEnclosedAlphanumericsIPAddress + plain2EnclosedAlphanumericsChar(IPAddressParts4EnclosedAlphanumerics[x][0]);
			if len(IPAddressParts4EnclosedAlphanumerics[x]) >= 2:
				returnEnclosedAlphanumericsIPAddress = returnEnclosedAlphanumericsIPAddress + plain2EnclosedAlphanumericsChar(IPAddressParts4EnclosedAlphanumerics[x][1]);
			if len(IPAddressParts4EnclosedAlphanumerics[x]) == 3:
				returnEnclosedAlphanumericsIPAddress = returnEnclosedAlphanumericsIPAddress + plain2EnclosedAlphanumericsChar(IPAddressParts4EnclosedAlphanumerics[x][2]);
			if x <= 2:
				returnEnclosedAlphanumericsIPAddress = returnEnclosedAlphanumericsIPAddress + plain2EnclosedAlphanumericsChar('.');
	return returnEnclosedAlphanumericsIPAddress

def convert(s, recurse_chunks=True, error_on_miss=False):
		if s in EnclosedAlphanumericsData:
			return random.choice(EnclosedAlphanumericsData[s])
		if recurse_chunks and len(s) > 1:
			return convert(s[:-1]) + convert(s[-1])
		if error_on_miss:
			raise Exception('Value not found: %s' % s)
		return s

def convert_ip(ip, sep='.'):
	return convert(sep).join([convert(chunk) for chunk in ip.split(sep)])

if len(sys.argv) < 4 or len(sys.argv) >= 6:
	print("\nUsage: python "+sys.argv[0]+" IP PORT WhiteListedDomain EXPORT(optional)\nUsage: python "+sys.argv[0]+" 169.254.169.254 80 www.google.com\nUsage: python "+sys.argv[0]+" 169.254.169.254 80 www.google.com export")
	exit(1)

redcolor='\x1b[0;31;40m'
greencolor='\x1b[0;32;40m'
yellowcolor='\x1b[0;33;40m'
bluecolor='\x1b[0;36;40m'
resetcolor='\x1b[0m'
arg1 = str(sys.argv[1])

if validIP(arg1) == False:
	print("\n",yellowcolor,arg1,resetcolor,redcolor," is not a valid IPv4 address in dotted decimal format, example: 123.123.123.123",resetcolor,sep='')

View on GitHub (pinned to 3bff425aca)

Solutions

  1. Call convert()/convert_ip() without error_on_miss (default False) when passthrough of unmappable characters is acceptable — that is the function's built-in fallback.
  2. Pre-filter input to the supported alphabet (digits, '.', a-f, x) and reject or normalize everything else (lowercase hex, drop IPv6/hosts) before calling with error_on_miss=True.
  3. Extend EnclosedAlphanumericsData with the missing glyphs (g-z circled equivalents) if coverage is genuinely required.
  4. Catch the exception at the call site and log which substring failed (the message already names it via 'Value not found: %s') to pinpoint bad input.

Example fix

# before
converted = convert(user_string, error_on_miss=True)   # raises on 'www.google.com'

# after (validate charset, then convert with strict flag only for known-good input)
SUPPORTED = set('0123456789.afx')
if set(user_string.lower()) <= SUPPORTED | {'.'}:
    converted = convert(user_string.lower(), error_on_miss=True)
else:
    converted = convert(user_string)   # passthrough fallback for unmappable chars
Defensive patterns

Strategy: fallback

Validate before calling

# Only strict-convert strings made of table-supported characters
SUPPORTED = set('0123456789.fx') | {'.'}
def is_convertible(s):
    return all(ch.lower() in SUPPORTED for ch in s)

result = convert(s, error_on_miss=is_convertible(s))  # strict only when safe

Type guard

def is_enclosed_convertible(s):
    """True when convert() can map every character without hitting the miss branch."""
    return all(ch in EnclosedAlphanumericsData or ch.lower() in EnclosedAlphanumericsData
               for ch in s)

Try / catch

try:
    out = convert(s, error_on_miss=True)
except Exception as e:
    msg = str(e)
    if msg.startswith('Value not found:'):
        missing = msg.split(':', 1)[1].strip()
        out = s  # fallback: keep original text, optionally log `missing`
    else:
        raise

Prevention

When it happens

Trigger: Calling convert() or convert_ip() with error_on_miss=True on input containing characters outside the table: a hostname like 'www.google.com' (w, g, o, l, m miss), an IPv6 address (':' misses), a hex IP with letters beyond a-f, or a malformed octet with stray characters. Conversely, plain IPv4 dotted-quads ('169.254.169.254' with default '.') always hit the digit/dot keys and never raise.

Common situations: Extending the SSRF testing script to convert whitelisted-domain strings or alternative notations and passing error_on_miss=True to surface bad data; refactoring call sites to reuse convert() for user-supplied strings (the earlier strict plain2EnclosedAlphanumericsChar at line 90 is the same idea without recursion); feeding locale/case variants (uppercase hex 0XA9) that the lowercase-only table cannot map.

Related errors


AI-assisted analysis of swisskyrepo/PayloadsAllTheThings@3bff425aca (2026-08-14). Data as JSON: /api/errors/bb914231576df1dc. Report an issue: GitHub.