syncthing/syncthing · error

dst write: %w

Error message

dst write: %w

What it means

While writing a copied block into the destination temp file (either via fs.CopyRange with a configured copy-range method, or limitedWriteAt which rate-limits a WriteAt), the write failed. This aborts the whole file pull for this pass; the temp file is kept so already-written blocks can be reused next attempt.

Source

Thrown at lib/model/folder_sendrecv.go:1513

	}

	dstFd, err := state.tempFile()
	if err != nil {
		// State is already marked as failed when an error is returned here.
		return false
	}

	if f.CopyRangeMethod != config.CopyRangeMethodStandard {
		err = f.withLimiter(ctx, func() error {
			dstFd.mut.Lock()
			defer dstFd.mut.Unlock()
			return fs.CopyRange(f.CopyRangeMethod.ToFS(), fd, dstFd.fd, srcOffset, block.Offset, int64(block.Size))
		})
	} else {
		err = f.limitedWriteAt(ctx, dstFd, buf, block.Offset)
	}
	if err != nil {
		state.fail(fmt.Errorf("dst write: %w", err))
		return false
	}
	return true
}

func (*sendReceiveFolder) verifyBuffer(buf []byte, block protocol.BlockInfo) error {
	if len(buf) != block.Size {
		return fmt.Errorf("length mismatch %d != %d", len(buf), block.Size)
	}

	hash := sha256.Sum256(buf)
	if !bytes.Equal(hash[:], block.Hash) {
		return fmt.Errorf("hash mismatch %x != %x", hash, block.Hash)
	}

	return nil
}

View on GitHub (pinned to 058bcd7334)

Solutions

  1. Check free space and disk health (df, dmesg for I/O errors) first
  2. Set the copy range method back to 'standard' in advanced settings if a non-standard method is configured
  3. Remount/repair flaky network filesystems (CIFS/NFS) hosting the folder
  4. Re-run the sync — if the temp file is corrupt, delete .syncthing.*.tmp for that file to force a fresh pull

Example fix

// before: options { copyRangeMethod: "copy_file_range" } // fails on overlayfs
// after:  options { copyRangeMethod: "standard" }
Defensive patterns

Strategy: fallback

Validate before calling

// If you configure a copy-range method, verify it works on the folder fs first
func copyRangeWorks(dir string, method config.CopyRangeMethod) bool {
    // write two probe files and attempt fs.CopyRange once; true iff no error
    // (omitted: mirrors folder_sendrecv copyBlock setup)
    return probeCopyRange(dir, method) == nil
}

Try / catch

// Wrap block writes; on failure containing ENOSPC/EIO surface disk state
// to the operator; on EBADF/ECANCELED discard the temp state and restart
// the file pull from scratch.

Prevention

When it happens

Trigger: copyBlock finisher: CopyRange fails (method unsupported on this filesystem — e.g. ioctl copy_file_range on overlayfs, or SPLICE/COPY_FILE_RANGE across incompatible mounts) or limitedWriteAt fails (ENOSPC disk full, EIO bad sector, EBADF fd closed because a previous failure finalized the temp file, or ctx cancelled mid-write).

Common situations: Disk full on the target; a copy-range method set globally (e.g. copy_file_range) that the folder's FS does not support; failing disk throwing I/O errors; file on a network mount that dropped.

Related errors


AI-assisted analysis of syncthing/syncthing@058bcd7334 (2026-08-15). Data as JSON: /api/errors/15029515b5663b39. Report an issue: GitHub.