- Installation
- Documentation
- Getting Started
- Connect
- Data Import and Export
- Overview
- Data Sources
- CSV Files
- JSON Files
- Overview
- Creating JSON
- Loading JSON
- Writing JSON
- JSON Type
- JSON Functions
- Format Settings
- Installing and Loading
- SQL to / from JSON
- Caveats
- Multiple Files
- Parquet Files
- Partitioning
- Appender
- INSERT Statements
- Lakehouse Formats
- Client APIs
- Overview
- ADBC
- C
- Overview
- Startup
- Configuration
- Query
- Data Chunks
- Vectors
- Values
- Types
- Prepared Statements
- Appender
- Table Functions
- Replacement Scans
- API Reference
- C++
- CLI
- Overview
- Arguments
- Dot Commands
- Output Formats
- Editing
- Friendly CLI
- Safe Mode
- Autocomplete
- Syntax Highlighting
- Known Issues
- Go
- Overview
- Connect
- Import Data
- Run Queries
- Handle Results
- Write User Defined Functions
- Profile and Monitor
- Troubleshoot
- Java (JDBC)
- Overview
- Connect
- Import Data
- Run Queries
- Handle Results
- Write User Defined Functions
- Profile and Monitor
- Deploy as Native Image
- Troubleshoot
- Node.js (Neo)
- ODBC
- Python
- Overview
- Data Ingestion
- Conversion between DuckDB and Python
- DB API
- Relational API
- Function API
- Types API
- Expression API
- Spark API
- API Reference
- Known Python Issues
- R
- Rust
- Overview
- Connect
- Import Data
- Run Queries
- Handle Results
- Write User Defined Functions
- Profile and Monitor
- Troubleshoot
- Wasm
- Tertiary Clients
- SQL
- Introduction
- Statements
- Overview
- ANALYZE
- ALTER TABLE
- ALTER VIEW
- ATTACH and DETACH
- CALL
- CHECKPOINT
- COMMENT ON
- COPY
- CREATE INDEX
- CREATE MACRO
- CREATE SCHEMA
- CREATE SECRET
- CREATE SEQUENCE
- CREATE TABLE
- CREATE VIEW
- CREATE TYPE
- DELETE
- DESCRIBE
- DROP
- EXPORT and IMPORT DATABASE
- INSERT
- LOAD / INSTALL
- MERGE INTO
- PIVOT
- Profiling
- SELECT
- SET / RESET
- SET VARIABLE
- SHOW and SHOW DATABASES
- SUMMARIZE
- Transaction Management
- UNPIVOT
- UPDATE
- USE
- VACUUM
- Query Syntax
- SELECT
- FROM and JOIN
- WHERE
- GROUP BY
- GROUPING SETS
- HAVING
- ORDER BY
- LIMIT and OFFSET
- SAMPLE
- Unnesting
- WITH
- WINDOW
- QUALIFY
- VALUES
- FILTER
- Set Operations
- Prepared Statements
- Data Types
- Overview
- Array
- Bitstring
- Blob
- Boolean
- Date
- Enum
- Geometry
- Interval
- List
- Literal Types
- Map
- NULL Values
- Numeric
- Struct
- Text
- Time
- Timestamp
- Time Zones
- Union
- Typecasting
- Variant
- Expressions
- Overview
- CASE Expression
- Casting
- Collations
- Comparisons
- IN Operator
- Logical Operators
- Star Expression
- Subqueries
- TRY
- Functions
- Overview
- Aggregate Functions
- Array Functions
- Bitstring Functions
- Blob Functions
- Date Format Functions
- Date Functions
- Date Part Functions
- Enum Functions
- Geometry Functions
- Interval Functions
- Lambda Functions
- List Functions
- Map Functions
- Nested Functions
- Numeric Functions
- Pattern Matching
- Regular Expressions
- Struct Functions
- Text Functions
- Time Functions
- Timestamp Functions
- Timestamp with Time Zone Functions
- Union Functions
- Utility Functions
- Window Functions
- Constraints
- Indexes
- Meta Queries
- DuckDB's SQL Dialect
- Overview
- Indexing
- Friendly SQL
- Keywords and Identifiers
- Order Preservation
- PostgreSQL Compatibility
- SQL Quirks
- PEG Parser
- Samples
- Configuration
- Extensions
- Overview
- Installing Extensions
- Advanced Installation Methods
- Distributing Extensions
- Versioning of Extensions
- Troubleshooting of Extensions
- Core Extensions
- Overview
- AutoComplete
- Avro
- AWS
- Azure
- Delta
- DuckLake
- Encodings
- Excel
- Full Text Search
- httpfs (HTTP and S3)
- Iceberg
- ICU
- inet
- jemalloc
- Lance
- MotherDuck
- MySQL
- ODBC
- Quack
- PostgreSQL
- Spatial
- SQLite
- TPC-DS
- TPC-H
- UI
- Unity Catalog
- Vortex
- VSS
- Quack Remote Protocol
- Guides
- Overview
- Data Viewers
- Database Integration
- File Formats
- Overview
- CSV Import
- CSV Export
- Directly Reading Files
- Directly Reading DuckDB Databases
- Excel Import
- Excel Export
- JSON Import
- JSON Export
- Parquet Import
- Parquet Export
- Querying Parquet Files
- File Access with the file: Protocol
- Meta Queries
- Describe Table
- EXPLAIN: Inspect Query Plans
- EXPLAIN ANALYZE: Profile Queries
- List Tables
- Summarize
- DuckDB Environment
- Network and Cloud Storage
- Overview
- HTTP Parquet Import
- S3 Parquet Import
- S3 Parquet Export
- S3 Iceberg Import
- S3 Express One
- GCS Import
- Cloudflare R2 Import
- DuckDB over HTTPS / S3
- Fastly Object Storage Import
- SeaweedFS Import
- Tigris Import
- ODBC
- Performance
- Overview
- Environment
- Import
- Schema
- Indexing
- Join Operations
- File Formats
- How to Tune Workloads
- My Workload Is Slow
- Out-of-Memory Issues
- Benchmarks
- Working with Huge Databases
- Python
- Installation
- Executing SQL
- Jupyter Notebooks
- marimo Notebooks
- SQL on Pandas
- Import from Pandas
- Export to Pandas
- Import from Numpy
- Export to Numpy
- SQL on Arrow
- Import from Arrow
- Export to Arrow
- Relational API on Pandas
- Multiple Python Threads
- Integration with Ibis
- Integration with Polars
- Integration with PyTorch
- Using fsspec Filesystems
- SQL Editors
- SQL Features
- AsOf Join
- Full-Text Search
- Graph Queries
- query and query_table Functions
- Merge Statement for SCD Type 2
- Timestamp Issues
- Snippets
- Creating Synthetic Data
- Dutch Railway Datasets
- Sharing Macros
- Analyzing a Git Repository
- Importing Duckbox Tables
- Copying an In-Memory Database to a File
- Calculating a Database Checksum
- Troubleshooting
- Glossary of Terms
- Browsing Offline
- Operations Manual
- Overview
- DuckDB's Footprint
- Installing DuckDB
- Logging
- User Agents
- Securing DuckDB
- Non-Deterministic Behavior
- Limits
- DuckDB Docker Container
- Development
- DuckDB Repositories
- Release Cycle
- Metrics
- Profiling
- Building DuckDB
- Overview
- Build Configuration
- Building Extensions
- Android
- Linux
- macOS
- Raspberry Pi
- Windows
- Python
- R
- Troubleshooting
- Unofficial and Unsupported Platforms
- Benchmark Suite
- Testing
- Internals
- Sitemap
- Live Demo
Overview
This page collects common issues encountered when using the DuckDB Go client, together with their workarounds. Because the client uses cgo to embed DuckDB, most build problems are cgo or linker problems. If you run into a problem that is not covered here, search the client's issue tracker on GitHub.
Classifying DuckDB Errors
The client returns a *duckdb.Error for errors reported by DuckDB. Use errors.As to handle these errors by category without parsing their messages:
_, err := db.Exec(query)
if err != nil {
var duckdbError *duckdb.Error
if errors.As(err, &duckdbError) {
switch duckdbError.Type {
case duckdb.ErrorTypeCatalog:
// Handle a missing table, view, or other catalog entry.
case duckdb.ErrorTypeConstraint:
// Handle a constraint violation.
}
}
}
duckdb.Error.Type is a duckdb.ErrorType. Other categories include ErrorTypeBinder, ErrorTypeParser, ErrorTypeConversion, ErrorTypeIO, ErrorTypeOutOfRange, and ErrorTypeInvalidInput. The Msg field contains the error message.
undefined: conn and Other cgo Errors
An undefined: conn error while building means the Go compiler has decided cgo is unavailable, so the DuckDB bindings were not compiled. There are two common causes:
-
Build tools are missing. cgo needs a C compiler and toolchain. On Debian or Ubuntu, install them with:
sudo apt-get update && sudo apt-get install build-essential -
Cross-compiling disables cgo. The Go compiler turns cgo off automatically when cross-compiling. Re-enable it and point at the right cross-compiler:
CC=⟨c_cross_compiler⟩ CGO_ENABLED=1 go build
Windows Setup
On Windows you need a compatible version of gcc and the necessary runtime libraries. One way is MSYS2: install it, then open an MSYS2 shell and install the UCRT64 toolchain:
pacman -S mingw-w64-ucrt-x86_64-gcc
Add gcc to the path, for example in PowerShell:
$env:PATH = "C:\msys64\ucrt64\bin;$env:PATH"
The package then compiles on Windows.
Linking DuckDB
By default the client statically links a pre-built DuckDB library into the binary, which increases the binary size but requires no separate DuckDB installation. Pre-built libraries ship for macOS (amd64, arm64), Linux (amd64, arm64), and Windows (amd64). If none of the pre-built libraries fit, link a custom library instead.
Linking a Custom Static Library
Build a DuckDB static library from source with DuckDB's bundle-library Makefile target, which produces build/release/libduckdb_bundle.a:
cd /path/to/duckdb
make bundle-library DUCKDB_PLATFORM=any BUILD_EXTENSIONS="icu;json;parquet;autocomplete"
Then build the Go module against that archive with the duckdb_use_static_lib build tag, passing the linker flags for the archive. For example, on macOS ARM64:
CGO_ENABLED=1 \
CPPFLAGS="-DDUCKDB_STATIC_BUILD" \
CGO_LDFLAGS="-lduckdb_bundle -lc++ -L/path/to/libs" \
go build -tags=duckdb_use_static_lib
This is also how a local DuckDB checkout is validated from the Go client, and how the client's own Makefile and CI build. It is required to target platforms without a pre-built library, including FreeBSD, for which DuckDB publishes no bundled library.
Linking a Dynamic Library
Alternatively, link dynamically against a libduckdb shared library on the system with the duckdb_use_lib build tag. Download the shared library (.so on Linux, .dylib on macOS) from the DuckDB releases page, then build and run with the library on the loader path:
# On Linux.
CGO_ENABLED=1 CGO_LDFLAGS="-lduckdb -L/path/to/libs" go build -tags=duckdb_use_lib main.go
LD_LIBRARY_PATH=/path/to/libs ./main
# On macOS.
CGO_ENABLED=1 CGO_LDFLAGS="-lduckdb -L/path/to/libs" go build -tags=duckdb_use_lib main.go
DYLD_LIBRARY_PATH=/path/to/libs ./main
TIMESTAMP versus TIMESTAMP_TZ
In the C API, DuckDB stores both TIMESTAMP and TIMESTAMP_TZ as the same instant, a number of microseconds since 1970-01-01 UTC, without offset information. When a time.Time is passed to the client, it is converted to that instant with UnixMicro(), even for TIMESTAMP_TZ, and scanning either type back returns an instant, because SQL types do not model a per-value time zone.
A bare time.Time binds as TIMESTAMP_TZ by default. When a different timestamp type is required, for example binding against a TIMESTAMP_NS column, force the type with duckdb.Typed():
row := db.QueryRow(query,
duckdb.Typed(start, duckdb.TYPE_TIMESTAMP_NS),
duckdb.Typed(end, duckdb.TYPE_TIMESTAMP_NS),
)
See Run Queries for the full example.
Scanning JSON Values
Starting with v2, scanning a JSON value directly into a string or []byte is no longer supported. Scan into any or into the duckdb.Composite wrapper instead, as shown in Run Queries. If a plain string or byte result is needed and the JSON structure is not, cast the column to ::VARCHAR or ::BLOB in SQL before scanning.
Further Reading
- Go Client — installation, build tags, and the bundled extensions.
- Connect — opening databases and the connection lifetime, whose failures are often build or linking problems.
- Run Queries — parameter binding, including the
duckdb.Typed()hint and JSON scanning.