Diagnostics

pgvector troubleshooting

Each problem below follows the same structure: the symptom, the likely cause, the fix with exact commands, and how to verify it worked. Every entry comes from the upstream documentation or changelog. Search or filter to find yours.

Query isn’t using the index

Likely cause: the query needs an ORDER BY that is the distance operator as a plain expression, in ascending order, together with a LIMIT. Ordering by an expression such as 1 - (embedding <=> '...') DESC will not use the index. On a small table a sequential scan may genuinely be faster.

Fix: order by the operator directly and add a LIMIT.

SQL
-- uses the index
SELECT * FROM items ORDER BY embedding <=> '[3,1,2]' LIMIT 5;

-- does NOT use the index (expression, not the operator)
SELECT * FROM items ORDER BY 1 - (embedding <=> '[3,1,2]') DESC LIMIT 5;

Verify: EXPLAIN shows an index scan. To confirm the index is usable, you can encourage the planner for one query:

SQL
BEGIN;
SET LOCAL enable_seqscan = off;
SELECT ...;
COMMIT;

Source: upstream READMERelated: querying

Parallel table scan isn’t used

Likely cause: the planner does not consider out-of-line storage in its cost estimates, which can make a serial scan look cheaper than a parallel one.

Fix: lower the parallel scan costs for the query, or store vectors inline.

SQL
BEGIN;
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_setup_cost = 1;
SELECT ...;
COMMIT;

-- or store vectors inline
ALTER TABLE items ALTER COLUMN embedding SET STORAGE PLAIN;

Verify: EXPLAIN shows a Gather / parallel scan node.

Source: upstream README

Fewer results after adding an HNSW index

Likely cause: results are limited by the dynamic candidate list, hnsw.ef_search, which defaults to 40. Dead tuples or a WHERE condition can reduce the count further.

Fix: raise hnsw.ef_search or enable iterative index scans.

SQL
SET hnsw.ef_search = 100;
SET hnsw.iterative_scan = strict_order;

Verify: the query returns the expected number of rows. Note that NULL vectors are not indexed, and zero vectors are not indexed for cosine distance.

Source: upstream READMERelated: iterative scans

Fewer results after adding an IVFFlat index

Likely cause: the index was created with too little data for its number of lists, or ivfflat.probes is too low.

Fix: drop the index, load more data, and rebuild it; raise probes or enable iterative scans.

SQL
DROP INDEX index_name;
-- load more data, then rebuild
SET ivfflat.probes = 10;
SET ivfflat.iterative_scan = relaxed_order;

Verify: result counts match expectations after rebuilding with more data.

Source: upstream READMERelated: IVFFlat

Some rows never appear in results

Likely cause: NULL vectors are not indexed, and for cosine distance, all-zero vectors are not indexed either. Those rows can never be returned by an index scan.

Fix: ensure every row has a non-null embedding, and avoid zero vectors when using cosine distance. Check for them:

SQL
SELECT count(*) FROM items WHERE embedding IS NULL;

Verify: the count is zero, or the remaining rows are ones you did not expect to match.

Source: upstream README

HNSW build is slow or reports “graph no longer fits into maintenance_work_mem”

Likely cause: the graph no longer fits in maintenance_work_mem, so the build spills to disk and slows down.

Fix: increase maintenance_work_mem, build after loading your initial data, and raise parallel workers. Do not set it so high that it exhausts server memory.

SQL
SET maintenance_work_mem = '8GB';
SET max_parallel_maintenance_workers = 7;  -- plus leader

Verify: the build finishes faster and no longer prints the notice after 100000 tuples. Check progress with pg_stat_progress_create_index.

Source: upstream README

Vacuuming an HNSW index is slow

Likely cause: vacuuming can take a while for HNSW indexes.

Fix: reindex first, then vacuum.

SQL
REINDEX INDEX CONCURRENTLY index_name;
VACUUM table_name;

Verify: vacuum completes noticeably faster on the reindexed index.

Source: upstream README

type "vector" does not exist

Likely cause: the extension is installed on the server but not enabled in the current database. Enabling is per-database.

Fix: connect to the database where you use vectors and enable the extension.

SQL
CREATE EXTENSION vector;

Verify: SELECT extversion FROM pg_extension WHERE extname = 'vector'; returns a version. If it fails, pgvector is not installed — see the install guide.

Source: upstream README

fatal error: postgres.h: No such file or directory

Likely cause: the PostgreSQL development headers are not installed on the machine doing the build.

Fix (Ubuntu / Debian): install the matching development package.

Shell
sudo apt install postgresql-server-dev-18

Verify: re-run make and the header is found.

Source: upstream READMEReplace 18 with your version.

Wrong PostgreSQL installation is targeted

Likely cause: the machine has multiple PostgreSQL installations and pg_config resolves to a different one than your server.

Fix: point PG_CONFIG at the correct binary, then rebuild (run make clean first if needed). Use --preserve-env when make install needs sudo.

Shell
export PG_CONFIG=/Library/PostgreSQL/18/bin/pg_config
make clean
make
sudo --preserve-env=PG_CONFIG make install

Verify: the extension is installed into the same PostgreSQL that runs your server. Common macOS paths: EDB /Library/PostgreSQL/18/bin/pg_config; Homebrew arm64 /opt/homebrew/opt/postgresql@18/bin/pg_config; Homebrew x86-64 /usr/local/opt/postgresql@18/bin/pg_config.

Source: upstream README

Illegal instruction when running the compiled extension

Likely cause: on some platforms pgvector compiles with -march=native for best performance, so the binary may not run on a CPU with different features — for example, when moving it to another machine.

Fix: compile for portability.

Shell
make OPTFLAGS=""

Verify: the extension loads and queries run without Illegal instruction on the target machine.

Source: upstream README

macOS build warning: no such sysroot directory

Likely cause: your PostgreSQL installation points to a path that no longer exists.

Fix: inspect the compile flags with pg_config --cppflags, then reinstall PostgreSQL to repair the path.

Shell
pg_config --cppflags

Verify: the warning no longer appears after reinstalling PostgreSQL and rebuilding.

Source: upstream README

Windows: Cannot open include file: 'postgres.h'

Likely cause: PGROOT does not point to your PostgreSQL installation.

Fix: set PGROOT correctly and rebuild.

Command Prompt
set "PGROOT=C:\Program Files\PostgreSQL\18"
nmake /F Makefile.win
nmake /F Makefile.win install

Verify: the header is found and the build completes.

Source: upstream README

Windows: error C2196: case value '4' already used

Likely cause: you are not using the x64 toolchain.

Fix: open the x64 Native Tools Command Prompt for Visual Studio, clean, and rebuild.

Command Prompt
nmake /F Makefile.win clean

Verify: the build no longer reports C2196.

Source: upstream README

Windows link error: unresolved external symbol float_to_shortest_decimal_bufn

Likely cause: a known issue with PostgreSQL 17.0 through 17.2.

Fix: upgrade PostgreSQL to 17.3 or newer.

Verify: the symbol resolves and linking succeeds.

Source: upstream READMEApplies to: PostgreSQL 17.0–17.2

Windows: Access is denied during install

Likely cause: insufficient permissions to write to the PostgreSQL directories.

Fix: re-run the installation from a command prompt opened as administrator.

Verify: nmake /F Makefile.win install completes without the error.

Source: upstream README

IVFFlat index gives wrong results after upgrading from a very old version

Likely cause: releases before 0.3.1 had an issue where inserts could silently corrupt IVFFlat indexes. If you upgraded from 0.2.7 or 0.3.0, existing indexes may be affected.

Fix: recreate all IVFFlat indexes after upgrading.

SQL
REINDEX INDEX index_name;
-- or DROP INDEX index_name; then recreate it

Verify: results match an exact search.

Source: CHANGELOG 0.3.1Applies to: upgrades from 0.2.7 / 0.3.0

Version-specific

Fixes in recent pgvector releases

If you are on an older version, upgrading may resolve the problem outright. These are the relevant fixes from the changelog. The current release is v0.8.6 (2026-07-29).

Relevant fixes by release
VersionDateFix
0.8.62026-07-29Fixed a buffer overflow with IVFFlat index build on 32-bit systems (#1006); fixed sparsevec array cast; fixed IVFFlat scan memory during nested loop joins.
0.8.52026-07-08Reduced memory usage for small tables during IVFFlat index builds.
0.8.42026-06-30Fixed hnsw graph not repaired error during HNSW vacuuming; fixed IVFFlat builds exceeding maintenance_work_mem.
0.8.32026-06-17Fixed possible HNSW index corruption during vacuuming; fixed a Hamming/Jaccard performance regression on PostgreSQL 18.
0.8.22026-02-25Fixed a buffer overflow with parallel HNSW index builds (#959); improved the Windows install target.
0.8.02024-10-30Added iterative index scans; improved index selection when filtering; dropped PostgreSQL 12.

Upgrade instructions are on the install page, or see the full changelog.

Need a working starting point? Generate the index and tuning SQL with the index planner, or grab copy-paste snippets from the cheatsheet.