Bug Description
In warehouse/identity/identity.go, the uploadFile() method opens the load file for uploading to object storage but never closes the file descriptor — on any path (filemanager creation error, upload error, or success).
This is the same defect class as #7071 (batchrouter upload()), but in the identity-resolution flow, which was not covered by that report.
Location
warehouse/identity/identity.go — function uploadFile(), line 455
Code
func (idr *Identity) uploadFile(ctx context.Context, filePath string, txn *sqlmiddleware.Tx, tableName string, totalRecords int) (err error) {
outputFile, err := os.Open(filePath)
if err != nil {
panic(err)
}
// ❌ no defer outputFile.Close() anywhere in the function
storageProvider := warehouseutils.ObjectStorageType(...)
uploader, err := filemanager.New(&filemanager.Settings{...})
if err != nil {
return err // fd leaked
}
output, err := uploader.Upload(ctx, outputFile, ...)
if err != nil {
return err // fd leaked
}
// ...
return err // fd also leaked on success
}
Impact
uploadFile() is called twice per identity-resolution sync — once for merge rules (processMergeRules, line 570) and once for identity mappings (line 581). Every warehouse sync with identity resolution enabled leaks 2 OS file descriptors for the lifetime of the process. Under sustained syncing this contributes to fd exhaustion (too many open files), the same failure mode described in #7071.
Secondary issue in the same function
A failed os.Open triggers panic(err), crashing the whole server, while every other error path in this function returns an error gracefully. A missing/unreadable temp file should surface as a sync failure, not a process crash.
Expected Behaviour
The file descriptor should be closed once the upload completes (success or failure), and open failure should return an error instead of panicking.
Suggested Fix
outputFile, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("opening load file %s: %w", filePath, err)
}
defer func() { _ = outputFile.Close() }()
This matches the pattern already used in the same package at identity.go:162 (tableRows.Close()) and in warehouse/validations/validate.go:405-411.
Environment
- File:
warehouse/identity/identity.go
- Function:
uploadFile() (lines 454–494)
- Affected: all warehouse destinations with identity resolution enabled
Bug Description
In
warehouse/identity/identity.go, theuploadFile()method opens the load file for uploading to object storage but never closes the file descriptor — on any path (filemanager creation error, upload error, or success).This is the same defect class as #7071 (batchrouter
upload()), but in the identity-resolution flow, which was not covered by that report.Location
warehouse/identity/identity.go— functionuploadFile(), line 455Code
Impact
uploadFile()is called twice per identity-resolution sync — once for merge rules (processMergeRules, line 570) and once for identity mappings (line 581). Every warehouse sync with identity resolution enabled leaks 2 OS file descriptors for the lifetime of the process. Under sustained syncing this contributes to fd exhaustion (too many open files), the same failure mode described in #7071.Secondary issue in the same function
A failed
os.Opentriggerspanic(err), crashing the whole server, while every other error path in this function returns an error gracefully. A missing/unreadable temp file should surface as a sync failure, not a process crash.Expected Behaviour
The file descriptor should be closed once the upload completes (success or failure), and open failure should return an error instead of panicking.
Suggested Fix
This matches the pattern already used in the same package at
identity.go:162(tableRows.Close()) and inwarehouse/validations/validate.go:405-411.Environment
warehouse/identity/identity.gouploadFile()(lines 454–494)