Validation

How to validate a URL programmatically.

The reliable way to validate a URL is to parse it and see if parsing succeeds — not to match it against a regular expression. Regexes for URLs either reject valid ones (IPv6 hosts, internationalized domains) or accept broken ones. Here’s the parse-based approach in three languages.

JavaScript: URL.canParse or try/catch

Modern JavaScript has URL.canParse(), which returns a boolean. Where it isn’t available, wrap new URL() in try/catch — if construction throws, the URL is invalid:

// Modern
URL.canParse('https://example.com/path');   // true
URL.canParse('not a url');                   // false

// Compatible fallback
function isValidUrl(s) {
  try { new URL(s); return true; }
  catch { return false; }
}

Require a specific scheme

Parsing accepts any valid URL, including javascript: and file:. If you only want web URLs, check the protocol after parsing:

function isHttpUrl(s) {
  let u;
  try { u = new URL(s); } catch { return false; }
  return u.protocol === 'http:' || u.protocol === 'https:';
}

Python

urlparse doesn’t throw on a bad URL, so validate by checking that the required components are present:

from urllib.parse import urlparse

def is_valid_http_url(s):
    try:
        u = urlparse(s)
    except ValueError:
        return False
    return u.scheme in ('http', 'https') and bool(u.netloc)

is_valid_http_url('https://example.com')   # True
is_valid_http_url('example.com')           # False (no scheme)
is_valid_http_url('javascript:alert(1)')   # False (scheme not http/https)

Java

Prefer java.net.URI for validation (it’s stricter and doesn’t trigger network resolution); a URISyntaxException means the string is malformed:

import java.net.URI;
import java.net.URISyntaxException;

static boolean isValidHttpUrl(String s) {
    try {
        URI u = new URI(s);
        String scheme = u.getScheme();
        return u.getHost() != null &&
               ("http".equals(scheme) || "https".equals(scheme));
    } catch (URISyntaxException e) {
        return false;
    }
}

Why not a regex?

URLs allow IPv6 hosts (http://[::1]/), internationalized domains, embedded credentials, unusual ports, and more. A single regex almost always gets some of these wrong — rejecting valid URLs or waving through broken ones. The URL parser in your language already implements the standard correctly, so use it.

Validation is not a security boundary

Two things a syntax check does not do:

Our decode-then-validate guide covers hardening user-supplied URLs. To check a single URL by hand, the URL validator gives a clear valid/invalid verdict with the reason.

About this page

Written and maintained by the urlencodedecode.com team. Every technical claim on this page is verified against primary sources — the RFCs (3986, 3629, 4648, 7578), the WHATWG URL Standard, and official vendor or language documentation — rather than second-hand summaries. When a source contradicts a common assumption, we follow the source and note the discrepancy. Corrections: contactus@urlencodedecode.com.

Common questions

Frequently asked.

Parse it rather than matching a regex. In JavaScript use URL.canParse(s) or wrap new URL(s) in try/catch. In Python check urlparse(s) has a scheme and netloc. In Java construct a java.net.URI and catch URISyntaxException. Parsing implements the URL standard correctly where regexes don't.

URLs allow IPv6 hosts, internationalized domains, embedded credentials, and unusual ports, so a single regex almost always rejects valid URLs or accepts malformed ones. The built-in URL parser already implements the standard, so it's far more reliable.

After parsing, check the scheme/protocol. In JavaScript, new URL(s).protocol should equal 'http:' or 'https:'. In Python, urlparse(s).scheme should be 'http' or 'https'. Parsing alone accepts any scheme, including javascript: and file:, so this extra check matters.

No. A syntactically valid URL can still point to a phishing site (open redirect) or an internal address (SSRF). Validate against an allowlist of trusted hosts before redirecting, and block internal IP ranges before your server fetches a user-supplied URL.

Construct a java.net.URI from the string and catch URISyntaxException for malformed input, then check getHost() is non-null and the scheme is http or https. URI is preferred over the older URL class because it validates syntax without triggering network resolution.

Related

Keep exploring.