PostgreSQL Error HV005: fdw_column_name_not_found
The HV005: fdw_column_name_not_found error occurs when PostgreSQL's Foreign Data Wrapper (FDW) cannot locate a specified column name in the remote data source. This typically happens when the local Foreign Table definition is out of sync with the actual remote table schema. It can appear across various FDW implementations including postgres_fdw, mysql_fdw, and oracle_fdw.
Top 3 Causes
1. Column Name Mismatch Between Foreign Table and Remote Table
The most common cause is a typo or naming convention difference between the local Foreign Table column and the actual remote column name.
-- WRONG: Remote table has 'user_name', but local foreign table defines 'username'
CREATE FOREIGN TABLE ft_users (
id integer,
username varchar(100) -- ❌ remote column is actually 'user_name'
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'users');
-- CORRECT: Use OPTIONS to map local name to remote column name
CREATE FOREIGN TABLE ft_users (
id integer OPTIONS (column_name 'id'),
username varchar(100) OPTIONS (column_name 'user_name') -- ✅ explicit mapping
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'users');
2. Remote Schema Changed Without Updating Foreign Table
If someone runs ALTER TABLE or renames a column on the remote server, the local Foreign Table definition becomes stale and triggers HV005.
-- Re-sync by re-importing the foreign schema
DROP FOREIGN TABLE IF EXISTS ft_users;
IMPORT FOREIGN SCHEMA public
LIMIT TO (users)
FROM SERVER remote_pg_server
INTO local_schema;
-- Verify the re-imported columns
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'local_schema'
AND table_name = 'users'
ORDER BY ordinal_position;
3. Incorrect OPTIONS (column_name ...) Value
Specifying a wrong remote column name in the column_name option of a Foreign Table column will directly cause this error.
-- Fix an incorrect column_name option on an existing foreign table
ALTER FOREIGN TABLE ft_users
ALTER COLUMN username OPTIONS (SET column_name 'user_name');
-- Check current column option mappings
SELECT
a.attname AS local_column,
fao.option_value AS remote_column
FROM pg_attribute a
JOIN pg_class c ON c.oid = a.attrelid
LEFT JOIN pg_options_to_table(a.attfdwoptions)
AS fao(option_name text, option_value text) ON fao.option_name = 'column_name'
WHERE c.relname = 'ft_users'
AND a.attnum > 0
AND NOT a.attisdropped;
Quick Fix Solutions
-- Step 1: Verify remote table columns via dblink
SELECT col_name
FROM dblink(
'host=remote_host dbname=mydb user=myuser password=mypass',
'SELECT column_name FROM information_schema.columns WHERE table_name = ''users'''
) AS t(col_name text);
-- Step 2: Drop and recreate the foreign table with correct names
DROP FOREIGN TABLE IF EXISTS ft_users;
CREATE FOREIGN TABLE ft_users (
id integer OPTIONS (column_name 'id'),
user_name varchar(100) OPTIONS (column_name 'user_name'),
email varchar(255) OPTIONS (column_name 'email')
)
SERVER remote_pg_server
OPTIONS (schema_name 'public', table_name 'users');
-- Step 3: Test the foreign table access
SELECT * FROM ft_users LIMIT 5;
Prevention Tips
1. Use IMPORT FOREIGN SCHEMA for reliable sync.
Instead of manually writing Foreign Table DDL, always use IMPORT FOREIGN SCHEMA to auto-generate accurate definitions directly from the remote source. Schedule periodic re-imports when remote schemas are subject to change.
-- Automate re-sync in a maintenance script
DO $$
BEGIN
EXECUTE 'DROP FOREIGN TABLE IF EXISTS local_schema.users';
EXECUTE 'IMPORT FOREIGN SCHEMA public LIMIT TO (users)
FROM SERVER remote_pg_server INTO local_schema';
RAISE NOTICE 'Sync done: %', now();
END;
$$;
2. Add schema validation to your CI/CD pipeline.
Before deploying, run a diff query comparing local Foreign Table columns against remote columns. If the result returns any rows, fail the deployment and alert the team.
-- Detect column mismatches before deployment
WITH local_cols AS (SELECT attname AS col FROM pg_attribute
WHERE attrelid = 'local_schema.ft_users'::regclass
AND attnum > 0 AND NOT attisdropped),
remote_cols AS (SELECT col_name AS col FROM dblink('...conn...','
SELECT column_name FROM information_schema.columns
WHERE table_name=''users''') AS t(col_name text))
SELECT 'MISMATCH' AS status, col FROM local_cols
WHERE col NOT IN (SELECT col FROM remote_cols);
-- Zero rows = safe to deploy ✅
Related Errors
| Code | Name | Notes |
|---|---|---|
| HV000 | fdw_error | Generic parent error for all FDW issues |
| HV00P | fdw_option_name_not_found | Invalid option name in OPTIONS clause |
| HV021 | fdw_inconsistent_descriptor_information | Column type mismatch in FDW descriptor |
| HV002 | fdw_dynamic_parameter_value_needed | Missing required dynamic FDW parameter |
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)