# Jones Act Waiver Tracker 

---

Documenting domestic cargo movements under the 
**March 17, 2026-August 16, 2026 waiver**

**On March 17, 2026, the Department of Homeland Security issued** [**the longest and broadest waiver of the Jones Act since at least 1950**](https://www.cato.org/commentary/defenders-jones-act-have-lost)**.** This interactive dashboard tracks the substantial economic activity that has emerged since the waiver was issued.

#### Additional context 

In nonwaiver times, the [**Jones Act**](http://cato.org/jonesact) restricts the transportation of cargo between US ports to vessels that are American-built, American-flagged, American-owned, and American-crewed. When the government determines that compliant vessels are unavailable or insufficient to meet national defense needs, it may issue emergency waivers allowing foreign-flagged ships to carry domestic cargo.

The March 17 waiver covers energy commodities and fertilizer inputs across roughly [**659 product categories**](https://content.govdelivery.com/accounts/USDHSCBP/bulletins/40f1204), including crude oil, refined petroleum products, natural gas, coal, ammonia, and fertilizers. The 60-day waiver was initially set to expire on May 17, 2026, and was subsequently extended for an additional 90 days, through August 16, 2026.

Operators utilizing the waiver are required to file voyage reports with the US Maritime Administration (MARAD), which publishes them [on its website](https://www.maritime.dot.gov/ports/domestic-shipping/domestic-shipping). The tracker above is built from those reports. Each voyage on the map is a domestic cargo movement that would have been unlawful had the Jones Act’s restrictions not been temporarily waived.

body { margin: 0; } 

import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js";
import define from "https://api.observablehq.com/d/3a87558830e6537f.js?v=4";
new Runtime().module(define, name => {
if (name === "viewof dashboard") return new Inspector(document.querySelector("#observablehq-viewof-dashboard-948ed421"));
});

// Report content height to the parent whenever it changes.
function sendHeight() {
parent.postMessage(
{ type: "observable-embed-height", height: document.documentElement.scrollHeight },
"*"
);
}
new ResizeObserver(sendHeight).observe(document.body);
window.addEventListener("load", sendHeight);

## Key Findings

- **The Gulf Coast to West Coast fuel trade springs to life**: In the waiver’s first 50 days, foreign-flagged tankers moved approximately 1.59 million barrels of energy products (excluding renewable diesel) from the Gulf Coast to the West Coast, which is roughly four times the volume moved by water on that route in all of 2025. In the waiver’s first 70 days, more gasoline and jet fuel [were moved](https://x.com/cpgrabow/status/2059273368948428967) from the Gulf Coast to the West Coast than in the entirety of 2020–2025.
- **Puerto Rico purchases US propane**: No liquefied petroleum gas (LPG) tankers exist in the Jones Act fleet. As a result, Puerto Rico had been effectively barred from bulk US propane purchases and was forced to import from [distant sources](https://x.com/cpgrabow/status/1868670472680083959). The waiver opened the global LPG fleet to domestic routes, allowing bulk propane to reach Puerto Rico from the US mainland for the first time.
- **Ammonia reaches American farmers**: Three voyages have carried anhydrous ammonia — a fertilizer and key precursor to other fertilizers — aboard LPG tankers.
- **Crude reaches Pennsylvania**: The waiver’s first 60 days saw four movements of crude oil, both Bakken oil and West Texas Intermediate, from Texas to the East Coast. In 2017, the CEO of a Jones Act tanker company [acknowledged](https://www.ft.com/content/b1ea86dc-ade6-11e7-aab9-abaa44b1e130) that without the law, “there probably would be more movements of crude oil from Texas to Philadelphia.” The waiver has borne that out.
- **Foreign vessels have supplemented, not replaced, the Jones Act fleet**: With the Jones Act tanker fleet [fully employed](https://jonesacttankertracker.com/), each foreign-flagged voyage represents demand that would otherwise have gone unmet.

(function () {
var SCRIPT = document.currentScript; // captured synchronously

function mount(node) {
if (SCRIPT && SCRIPT.parentNode) SCRIPT.parentNode.insertBefore(node, SCRIPT);
else document.body.appendChild(node);
}

(async function () {
var SHEET_ID = "1P6MDZYvjLlH5xu8YibvniiCjv9Fkm1tVSRCrpIL8lKo";
var GID = 0;
var PAD = 24; // right padding (px)
var PADL = 12; // left padding (px) — smaller so the arrow sits evenly in the corner

// ---- fetch ----
const res = await fetch(
`https://docs.google.com/spreadsheets/d/${SHEET_ID}/export?format=csv&gid=${GID}`);
if (!res.ok) throw new Error(`Sheet fetch failed: ${res.status} ${res.statusText}`);
const text = await res.text();
if (text.trim().startsWith("<"))
throw new Error("Sheet returned HTML, not CSV — set sharing to 'Anyone with the link'.");

// ---- minimal CSV parser (quoted fields, embedded commas + newlines) ----
function parseCSV(str) {
const rows = []; let row = [], f = "", q = false;
for (let i = 0; i < str.length; i++) {
const c = str[i];
if (q) { if (c === '"') { if (str[i + 1] === '"') { f += '"'; i++; } else q = false; } else f += c; }
else if (c === '"') q = true;
else if (c === ",") { row.push(f); f = ""; }
else if (c === "\r") { /* skip */ }
else if (c === "\n") { row.push(f); rows.push(row); row = []; f = ""; }
else f += c;
}
if (f.length || row.length) { row.push(f); rows.push(row); }
const h = rows.shift().map(x => x.trim());
return rows
.filter(r => r.length > 1 || (r.length === 1 && r[0].trim() !== ""))
.map(r => Object.fromEntries(h.map((k, i) => [k, r[i] ?? ""])));
}

// ---- state + port extraction ----
const STATES = ["Alabama","Alaska","Arizona","Arkansas","California","Colorado",
"Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana",
"Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan",
"Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire",
"New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma",
"Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee",
"Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming",
"District of Columbia","Puerto Rico","Guam","Bahamas"];
const STSET = new Set(STATES);
const norm = (s) => String(s ?? "").replace(/\s+/g, " ").trim();

// earliest known state name in the field (handles "A / B" + trailing junk)
const deriveState = (field) => {
const s = norm(field);
let best = null, bp = Infinity, bl = 0;
for (const st of STATES) {
const i = s.indexOf(st);
if (i !== -1 && (i < bp || (i === bp && st.length > bl))) { best = st; bp = i; bl = st.length; }
}
return best;
};
// primary (first) port of an endpoint, as a bare city label
const portCanon = (field) => {
const state = deriveState(field);
let seg = norm(field).split(" / ")[0].split(" via ")[0].replace(/\s*\(.*$/, "").trim();
let parts = seg.split(",").map(p => p.trim()).filter(Boolean);
if (parts.length && STSET.has(parts[parts.length - 1])) parts = parts.slice(0, -1);
const city = parts.join(", ").trim();
return { state, label: (city || state || seg) };
};

// ---- aggregate ----
// State rows: route crosses the state line => import for the arrival state,
// export for the departure state; same state => intra.
// Port rows: a route arriving at a port => import there, departing => export,
// loaded & discharged at the same port => intra.
const states = new Map();
const portsByState = new Map();
const esf = (s) => { if (!states.has(s)) states.set(s, { state: s, import: 0, export: 0, intra: 0 }); return states.get(s); };
const epf = (s, p) => {
if (!portsByState.has(s)) portsByState.set(s, new Map());
const m = portsByState.get(s);
if (!m.has(p)) m.set(p, { label: p, import: 0, export: 0, intra: 0 });
return m.get(p);
};
for (const r of parseCSV(text)) {
const L = portCanon(r.load_port), U = portCanon(r.unload_port);
if (!L.state || !U.state) continue;
if (L.state === U.state) esf(L.state).intra++;
else { esf(L.state).export++; esf(U.state).import++; }
if (L.label === U.label && L.state === U.state) epf(L.state, L.label).intra++;
else { epf(L.state, L.label).export++; epf(U.state, U.label).import++; }
}
const total = (d) => d.import + d.export + d.intra;
const byTotal = (a, b) => total(b) - total(a) || a.label.localeCompare(b.label);
const stateRows = [...states.values()]
.sort((a, b) => total(b) - total(a) || a.state.localeCompare(b.state));

// Size the name column to the widest label across ALL rows — including
// ports inside collapsed states — so the width is fixed and doesn't shift
// when states expand/collapse. Measured with the actual font.
// ---- render ----
const root = document.createElement("div");
root.className = "srt";
root.innerHTML = `<style>
.srt { font: 18px/1.4 "Inter", system-ui, sans-serif; color: #222; width: 680px; max-width: 100%; box-sizing: border-box; padding: 0; margin: 0 auto; container-type: inline-size; }
.srt.srt-head,.srt.srt-state,.srt.srt-port {
display: grid; grid-template-columns: minmax(0, 1fr) 76px 76px 76px; column-gap: 8px; align-items: center;
}
.srt.srt-head {
color: #555; padding: 0 ${PAD}px 6px ${PADL}px; border-bottom: 2px solid #999;
}
.srt.srt-head.n,.srt.num { text-align: right; font-variant-numeric: tabular-nums; padding-right: 6px; }
.srt.srt-head.n { font-weight: 700; }
.srt.srt-group { position: relative; }
.srt.srt-state {
cursor: pointer; user-select: none; padding: 7px ${PAD}px 7px ${PADL}px; border-bottom: 1px solid #ececec;
}
.srt.srt-group.open.srt-state { border-bottom: none; }
.srt.name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.srt.chevron { width: 14px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
line-height: 0; transition: transform 0.15s ease; transform: rotate(-135deg); }
.srt.chevron svg { width: 8px; height: 8px; stroke: #555; stroke-width: 1.5;
stroke-linecap: square; fill: none; }
.srt.srt-group.open.chevron { transform: rotate(-45deg); }
.srt.st-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.srt.srt-ports {
display: none; background: #fbfbfb; margin: 6px 0; border-radius: 2px; padding: 6px 0;
box-shadow: inset 0 4px 6px -4px rgba(0,0,0,0.18), inset 0 -2px 4px -3px rgba(0,0,0,0.10);
}
.srt.srt-group.open.srt-ports { display: block; }
.srt.srt-port { padding: 3px ${PAD}px 3px ${PADL}px; }
.srt.srt-port.name { padding-left: 42px; }
.srt.srt-port.p-name { color: #444; min-width: 0; overflow-wrap: anywhere; }
.srt.zero { color: #cfcfcf; }
.srt.srt-foot {
display: grid; grid-template-columns: minmax(0, 1fr) 76px 76px 76px; column-gap: 8px;
font-weight: 600; padding: 7px ${PAD}px 0 ${PADL}px; border-top: 2px solid #999;
}
.srt.srt-foot.num { text-align: right; font-variant-numeric: tabular-nums; }
.srt.srt-head.n.abbr { display: none; }
@container (max-width: 400px) {
.srt.srt-head,.srt.srt-state,.srt.srt-port,.srt.srt-foot {
grid-template-columns: minmax(0, 1fr) 44px 44px 44px;
}
.srt.srt-head.n.full { display: none; }
.srt.srt-head.n.abbr { display: inline; }
}
`;

const head = document.createElement("div");
head.className = "srt-head";
head.innerHTML = `<span>State / port` +
`<span class="n"><span class="full">Import<span class="abbr">Im` +
`<span class="n"><span class="full">Export<span class="abbr">Ex` +
`<span class="n"><span class="full">Intra<span class="abbr">In`;
root.appendChild(head);

const num = (v) => `<span class="num${v === 0 ? " zero" : ""}">${v}`;
const chevronSVG = `<span class="chevron"><svg viewBox="0 0 10 10"><path d="M 2 1 L 2 8 L 9 8"/>`;

const rowsWrap = document.createElement("div");
rowsWrap.className = "srt-rows";

for (const s of stateRows) {
const group = document.createElement("div");
group.className = "srt-group";

const header = document.createElement("div");
header.className = "srt-state";
header.innerHTML =
`<span class="name">${chevronSVG}<span class="st-name">${s.state}` +
num(s.import) + num(s.export) + num(s.intra);

const ports = document.createElement("div");
ports.className = "srt-ports";
const plist = [...portsByState.get(s.state).values()].sort(byTotal);
ports.innerHTML = plist.map(p =>
`<div class="srt-port"><span class="name"><span class="p-name">${p.label}` +
num(p.import) + num(p.export) + num(p.intra) + `

` ).join(""); header.addEventListener("click", () =&gt; group.classList.toggle("open")); group.appendChild(header); group.appendChild(ports); rowsWrap.appendChild(group); } root.appendChild(rowsWrap); const sum = (k) =&gt; stateRows.reduce((t, d) =&gt; t + d[k], 0); const foot = document.createElement("div"); foot.className = "srt-foot"; foot.innerHTML = `Total` + `${sum("import")}${sum("export")}${sum("intra")}`; root.appendChild(foot); mount(root); })().catch(function (err) { var e = document.createElement("div"); e.style.cssText = "font:14px system-ui,sans-serif;color:#b00;"; e.textContent = "Routes table failed to load: " + (err &amp;&amp; err.message ? err.message : err); mount(e); }); })(); 

#### Further Reading 

[![LNG tanker ](/sites/cato.org/files/styles/content_teaser/public/2024-01/LNG%20tanker%20.jpg?itok=Ow8DdVBX)](https://www.cato.org/blog/jones-act-waiver-data-reveals-universe-blocked-american-trade) 

blog 

### [Waiver Data Reveal How the Jones Act Blocks American Trade](/blog/jones-act-waiver-data-reveals-universe-blocked-american-trade) 

By [Colin Grabow](https://www.cato.org/people/colin-grabow) 

A new interactive infographic tracking all 45 voyages completed under the Trump administration’s March 2026 Jones Act waiver helps reveal the scale of domestic maritime trade that the 1920 law has long suppressed.

[![Jones Act Reform Project Page Hover Card](/sites/cato.org/files/styles/content_teaser/public/2025-02/GettyImages-2153829073.jpg?itok=8Xj8cJCF)](https://www.cato.org/commentary/defenders-jones-act-have-lost) 

Commentary 

### [Defenders of the Jones Act Have Lost](/commentary/defenders-jones-act-have-lost) 

By [Scott Lincicome](https://www.cato.org/people/scott-lincicome) 

For more than a century, the Jones Act has survived on purported economic and security grounds.

[![What to Expect on Trade Policy in the Biden Administration](/sites/cato.org/files/styles/content_teaser/public/2021-03/sponsor-ebriefing-trade-biden.jpg?itok=rtAKa6jQ)](https://www.cato.org/commentary/protectionism-steroids) 

Commentary 

### [Protectionism on Steroids](/commentary/protectionism-steroids) 

By [Colin Grabow](https://www.cato.org/people/colin-grabow) 

The case for dumping the Jones Act into the ashcan of history is a no-brainer.