diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c
index c3039e8eebb058705f5d987d84a5ed90377d0f00..ddee3180ae6089e835da2901e9c6c3e7eb504ba6 100644
--- a/src/lib-sieve-tool/sieve-tool.c
+++ b/src/lib-sieve-tool/sieve-tool.c
@@ -577,6 +577,10 @@ void sieve_tool_dump_binary_to
 			(void) sieve_hexdump(sbin, dumpstream);
 		else
 			(void) sieve_dump(sbin, dumpstream, FALSE);
+		if (o_stream_nfinish(dumpstream) < 0) {
+			i_fatal("write(%s) failed: %s", filename,
+				o_stream_get_error(dumpstream));
+		}
 		o_stream_destroy(&dumpstream);
 	} else {
 		i_fatal("Failed to create stream for sieve code dump.");
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 3dd28bca727e0e6039ea963021bb6f85d29d8c9c..9827a479666bb1723ab85d98ad4dbaf1cea1042d 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -395,15 +395,12 @@ static int act_redirect_send
 		if ( new_msg_id != NULL )
 			rfc2822_header_write(hdr, "Message-ID", new_msg_id);
 
-		o_stream_send(output, str_data(hdr), str_len(hdr));
+		o_stream_nsend(output, str_data(hdr), str_len(hdr));
 	} T_END;
 
-	ret = o_stream_send_istream(output, input);
+	o_stream_nsend_istream(output, input);
 
-	/* blocking i/o required */
-	i_assert( ret != 0 );
-
-	if (ret < 0 && input->stream_errno != 0) {
+	if (input->stream_errno != 0) {
 		sieve_result_critical(aenv,
 			"redirect action: failed to read input message",
 			"redirect action: read(%s) failed: %s",
diff --git a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
index 5a2cd8b596010ddade7bd32fbdd2d18dd35ca2f4..dc45abad5ae876d467db7ab0f276dc87f366e06c 100644
--- a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
@@ -632,7 +632,7 @@ static int ntfy_mailto_send
 		sieve_smtp_add_rcpt(sctx, recipients[i].normalized);
 
 	output = sieve_smtp_send(sctx);
-	o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	if ( (ret=sieve_smtp_finish(sctx, &error)) <= 0 ) {
 		if (ret < 0)  {
diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c
index bacbf31ef367528cc7197154bb7154efa3e3e72e..74ec2f63a4e9876ca1e3ae8ab8cd44d82b4c8355 100644
--- a/src/lib-sieve/plugins/notify/cmd-notify.c
+++ b/src/lib-sieve/plugins/notify/cmd-notify.c
@@ -776,7 +776,7 @@ static bool act_notify_send
 	str_printfa(msg, "\r\n%s\r\n", act->message);
 
 	output = sieve_smtp_send(sctx);
-	o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	if ( (ret=sieve_smtp_finish(sctx, &error)) <= 0 ) {
 		if (ret < 0) {
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 1f60c583550a167202899c3e44bfdb35fe944552..755bcc96cc44067ef30b446382806171ea39f321 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -986,7 +986,7 @@ static int act_vacation_send
 	}
 
 	str_printfa(msg, "%s\r\n", ctx->reason);
-  o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	/* Close smtp session */
 	if ( (ret=sieve_smtp_finish(sctx, &error)) <= 0 ) {
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c
index eb446297d49e6433953432b69555a8c4649475dd..7e8f9226a1cf8c9d20eb3d27c4e22bd8cd4cfb83 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c
@@ -526,7 +526,7 @@ static int act_report_send
 	rfc2822_header_write(msg, "Content-Disposition", "inline");
 
 	str_printfa(msg, "\r\n%s\r\n\r\n", act->message);
-	o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	/* Machine-readable report */
   str_truncate(msg, 0);
@@ -562,7 +562,7 @@ static int act_report_send
 	}
 	str_append(msg, "\r\n");
 
-	o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	/* Original message */
   str_truncate(msg, 0);
@@ -577,7 +577,7 @@ static int act_report_send
 	rfc2822_header_write(msg,
 		"Content-Disposition", "attachment");
 	str_append(msg, "\r\n");
-	o_stream_send(output, str_data(msg), str_len(msg));
+	o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	if (act->headers_only) {
 		struct message_size hdr_size;
@@ -594,12 +594,9 @@ static int act_report_send
 			"report action: failed to read input message");
 	}
 
-  ret = o_stream_send_istream(output, input);
+	o_stream_nsend_istream(output, input);
 
-	/* blocking i/o required */
-	i_assert( ret != 0 );
-
-	if ( ret < 0 && input->stream_errno != 0 ) {
+	if ( input->stream_errno != 0 ) {
 		/* Error; clean up */
 		sieve_result_critical(aenv,
 			"report action: failed to read input message",
@@ -615,7 +612,7 @@ static int act_report_send
 	if (!act->headers_only)
 		str_printfa(msg, "\r\n");
 	str_printfa(msg, "\r\n--%s--\r\n", boundary);
-  o_stream_send(output, str_data(msg), str_len(msg));
+  o_stream_nsend(output, str_data(msg), str_len(msg));
 
 	/* Finish sending message */
 	if ( (ret=sieve_smtp_finish(sctx, &error)) <= 0 ) {
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 6ab4b066c5b6606dfd53d9b8b0a23f984c2e7b1b..e499e835b7362d66f82109638c5eeea13d1b8328 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -876,7 +876,7 @@ static int sieve_action_do_reject_mail
 	str_printfa(hdr, "--%s\r\n", boundary);
 	rfc2822_header_write(hdr, "Content-Type", "message/rfc822");
 	str_append(hdr, "\r\n");
-	o_stream_send(output, str_data(hdr), str_len(hdr));
+	o_stream_nsend(output, str_data(hdr), str_len(hdr));
 
 	if (mail_get_hdr_stream(msgdata->mail, NULL, &input) == 0) {
     /* Note: If you add more headers, they need to be sorted.
@@ -893,15 +893,13 @@ static int sieve_action_do_reject_mail
 		N_ELEMENTS(exclude_headers),
 		*null_header_filter_callback, (void *)NULL);
 
-    ret = o_stream_send_istream(output, input);
+    o_stream_nsend_istream(output, input);
     i_stream_unref(&input);
-
-    i_assert(ret != 0);
   }
 
   str_truncate(hdr, 0);
   str_printfa(hdr, "\r\n\r\n--%s--\r\n", boundary);
-  o_stream_send(output, str_data(hdr), str_len(hdr));
+  o_stream_nsend(output, str_data(hdr), str_len(hdr));
 
 	if ( (ret=sieve_smtp_finish(sctx, &error)) <= 0 ) {
 		if ( ret < 0 ) {
diff --git a/src/lib-sieve/sieve-binary-dumper.c b/src/lib-sieve/sieve-binary-dumper.c
index 7a4b2283e7042b78235deb5f52b4bca77b94051c..48bb9c71ec104ac3278311f332e91b32b2301aad 100644
--- a/src/lib-sieve/sieve-binary-dumper.c
+++ b/src/lib-sieve/sieve-binary-dumper.c
@@ -71,7 +71,7 @@ void sieve_binary_dumpf
 	str_vprintfa(outbuf, fmt, args);
 	va_end(args);
 
-	o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 void sieve_binary_dump_sectionf
@@ -86,7 +86,7 @@ void sieve_binary_dump_sectionf
 	str_printfa(outbuf, ":\n\n");
 	va_end(args);
 
-	o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 /*
@@ -279,13 +279,13 @@ void sieve_binary_dumper_hexdump
 			}
 
 			str_append(line, "|\n");
-			o_stream_send(stream, str_data(line), str_len(line));
+			o_stream_nsend(stream, str_data(line), str_len(line));
 			str_truncate(line, 0);
 			offset += len;
 		}
 
 		str_printfa(line, "%08llx\n", (unsigned long long) offset);
-		o_stream_send(stream, str_data(line), str_len(line));
+		o_stream_nsend(stream, str_data(line), str_len(line));
 	}
 }
 
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index 3c098b6699875314695222268d1c0269bcb6784c..c761200bd7372a1c518cdf26aace990ddae44957 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -163,7 +163,7 @@ void sieve_code_dumpf
 	str_append_c(outbuf, '\n');
 	va_end(args);
 
-	o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(denv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 static inline void sieve_code_line_mark
@@ -246,7 +246,7 @@ void sieve_code_dumper_run(struct sieve_code_dumper *cdumper)
 	address = &(denv->offset);
 
 	/* Heading */
-	o_stream_send_str(denv->stream, "Address   Line  Code\n");
+	o_stream_nsend_str(denv->stream, "Address   Line  Code\n");
 
 	/* Load debug block */
 	sieve_code_mark(denv);
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 908e4fd00de1b729a52883914f9b8351d287342b..014fcbc96424b23faff2ef4f6c3624d73510e607 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -728,7 +728,7 @@ void sieve_result_vprintf
 
 	str_vprintfa(outbuf, fmt, args);
 
-	o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 void sieve_result_printf
@@ -753,7 +753,7 @@ void sieve_result_action_printf
 	str_append_c(outbuf, '\n');
 	va_end(args);
 
-	o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 void sieve_result_seffect_printf
@@ -768,7 +768,7 @@ void sieve_result_seffect_printf
 	str_append_c(outbuf, '\n');
 	va_end(args);
 
-	o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
+	o_stream_nsend(penv->stream, str_data(outbuf), str_len(outbuf));
 }
 
 static void sieve_result_print_side_effects
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 0c876eed57ae8d43eef2f517d25800874db0f272..f82609c13eda85a572b71286f3694a7083359192 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -865,6 +865,7 @@ int sieve_trace_log_create
 			return -1;
 		}
 		output = o_stream_create_fd_autoclose(&fd, 0);
+		o_stream_set_name(output, path);
 	}
 
 	trace_log = i_new(struct sieve_trace_log, 1);
@@ -935,7 +936,7 @@ void sieve_trace_log_write_line
 	struct const_iovec iov[2];
 
 	if (line == NULL) {
-		o_stream_send_str(trace_log->output, "\n");
+		o_stream_nsend_str(trace_log->output, "\n");
 		return;
 	}
 
@@ -944,7 +945,7 @@ void sieve_trace_log_write_line
 	iov[0].iov_len = str_len(line);
 	iov[1].iov_base = "\n";
 	iov[1].iov_len = 1;
-	o_stream_sendv(trace_log->output, iov, 2);
+	o_stream_nsendv(trace_log->output, iov, 2);
 }
 
 void sieve_trace_log_free(struct sieve_trace_log **_trace_log)
@@ -953,6 +954,11 @@ void sieve_trace_log_free(struct sieve_trace_log **_trace_log)
 
 	*_trace_log = NULL;
 
+	if (o_stream_nfinish(trace_log->output) < 0) {
+		i_error("write(%s) failed: %s",
+			o_stream_get_name(trace_log->output),
+			o_stream_get_error(trace_log->output));
+	}
 	o_stream_destroy(&trace_log->output);
 	i_free(trace_log);
 }
diff --git a/src/managesieve-login/managesieve-proxy.c b/src/managesieve-login/managesieve-proxy.c
index fa96c783bb57c2eb1ccf907d131492394d574da7..943430637fad23f239885808cb458851fa871b88 100644
--- a/src/managesieve-login/managesieve-proxy.c
+++ b/src/managesieve-login/managesieve-proxy.c
@@ -392,7 +392,7 @@ int managesieve_proxy_parse_line(struct client *client, const char *line)
 				msieve_client->proxy_state = MSIEVE_PROXY_STATE_AUTH;
 			}
 
-			(void)o_stream_send(output, str_data(command), str_len(command));
+			o_stream_nsend(output, str_data(command), str_len(command));
 		}
 		return 0;
 
@@ -444,7 +444,7 @@ int managesieve_proxy_parse_line(struct client *client, const char *line)
 				}
 				msieve_client->proxy_state = MSIEVE_PROXY_STATE_AUTH;
 			}
-			(void)o_stream_send(output, str_data(command), str_len(command));
+			o_stream_nsend(output, str_data(command), str_len(command));
 		}
 		return 0;
 
@@ -457,7 +457,7 @@ int managesieve_proxy_parse_line(struct client *client, const char *line)
 				client_proxy_failed(client, TRUE);
 				return -1;
 			}
-			(void)o_stream_send(output, str_data(command), str_len(command));
+			o_stream_nsend(output, str_data(command), str_len(command));
 			msieve_client->proxy_state = MSIEVE_PROXY_STATE_AUTH;
 			return 0;
 		}
@@ -484,7 +484,7 @@ int managesieve_proxy_parse_line(struct client *client, const char *line)
 				client_proxy_failed(client, TRUE);
 				return -1;
 			}
-			(void)o_stream_send(output, str_data(command), str_len(command));
+			o_stream_nsend(output, str_data(command), str_len(command));
 			return 0;
 		}
 
@@ -500,7 +500,7 @@ int managesieve_proxy_parse_line(struct client *client, const char *line)
 			/* Send this line to client. */
 			str_append(str, line );
 			str_append(str, "\r\n");
-			(void)o_stream_send(client->output, str_data(str), str_len(str));
+			o_stream_nsend(client->output, str_data(str), str_len(str));
 
 			(void)client_skip_line(msieve_client);
 			client_proxy_finish_destroy_client(client);
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
index 8b4f12d8b94b99f5f6cdd35b210d8bf2f280bf40..740c497e261b179b6d1ddaace09499c60fb4bcf5 100644
--- a/src/sieve-tools/sieve-filter.c
+++ b/src/sieve-tools/sieve-filter.c
@@ -132,7 +132,7 @@ static int filter_message
 		sieve_error_handler_unref(&action_ehandler);
 
 	} else {
-		(void)o_stream_send_str(sfctx->teststream,
+		o_stream_nsend_str(sfctx->teststream,
 			t_strdup_printf(">> Filtering message:\n\n"
 				"  ID:      %s\n"
 			  "  Date:    %s\n"
@@ -288,8 +288,10 @@ static int filter_mailbox
 	sfctx.data = sfdata;
 
 	/* Create test stream */
-	if ( !sfdata->execute )
+	if ( !sfdata->execute ) {
 		sfctx.teststream = o_stream_create_fd(1, 0, FALSE);
+		o_stream_set_no_error_handling(sfctx.teststream, TRUE);
+	}
 
 	/* Start move mailbox transaction */
 
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index 3d884544e71432f7831a9aa9b277a8368b0dedba..cbfc52cc6331777cc39fcd4dbc32277717c534dc 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -281,6 +281,7 @@ int main(int argc, char **argv)
 		if ( !execute ) {
 			action_ehandler = NULL;
 			teststream = o_stream_create_fd(1, 0, FALSE);
+			o_stream_set_no_error_handling(teststream, TRUE);
 		} else {
 			action_ehandler = sieve_prefix_ehandler_create
 				(ehandler, NULL, t_strdup_printf("msgid=%s",
@@ -342,7 +343,7 @@ int main(int argc, char **argv)
 			sfiles = array_get(&scriptfiles, &count);
 			for ( i = 0; i < count && more; i++ ) {
 				if ( teststream != NULL )
-					o_stream_send_str(teststream,
+					o_stream_nsend_str(teststream,
 						t_strdup_printf("\n## Executing script: %s\n", sfiles[i]));
 
 				/* Close previous script */
@@ -371,7 +372,7 @@ int main(int argc, char **argv)
 			/* Execute/Test main script */
 			if ( more && ret > 0 ) {
 				if ( teststream != NULL )
-					o_stream_send_str(teststream,
+					o_stream_nsend_str(teststream,
 						t_strdup_printf("## Executing script: %s\n", scriptfile));
 
 				/* Close previous script */
diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c
index 47bc601162352fecc244843160d57c9bfd4cec28..49dc7a890c53196fd60bfdb565608468fbbde21f 100644
--- a/src/testsuite/testsuite-result.c
+++ b/src/testsuite/testsuite-result.c
@@ -87,10 +87,11 @@ void testsuite_result_print
 	struct ostream *out;
 
 	out = o_stream_create_fd(1, 0, FALSE);
+	o_stream_set_no_error_handling(out, TRUE);
 
-	o_stream_send_str(out, "\n--");
+	o_stream_nsend_str(out, "\n--");
 	sieve_result_print(_testsuite_result, renv->scriptenv, out, NULL);
-	o_stream_send_str(out, "--\n\n");
+	o_stream_nsend_str(out, "--\n\n");
 
 	o_stream_destroy(&out);
 }
diff --git a/src/testsuite/testsuite-smtp.c b/src/testsuite/testsuite-smtp.c
index ee5578f1e9b6d47b876a9e33b1091d4bffbf6e85..b273135c5db5a321bd4d79b442945f110c2fd0de 100644
--- a/src/testsuite/testsuite-smtp.c
+++ b/src/testsuite/testsuite-smtp.c
@@ -123,12 +123,18 @@ int testsuite_smtp_finish
 	void *handle, const char **error_r ATTR_UNUSED)
 {
 	struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle;
+	int ret = 1;
 
+	if (o_stream_nfinish(smtp->output) < 0) {
+		i_error("write(%s) failed: %s", smtp->msg_file,
+			o_stream_get_error(smtp->output));
+		ret = -1;
+	}
 	o_stream_unref(&smtp->output);
 	i_free(smtp->msg_file);
 	i_free(smtp->return_path);
 	i_free(smtp);
-	return 1;
+	return ret;
 }
 
 /*