### Team
- [X] I've assigned a team label to this issue
### Severity
Intermit…tent problem for several customers
### Version
2021.2.7580, 2021.2.7650
### Latest Version
Not applicable
### What happened?
When running a health check there is an I/O error saving the results due to "thread exit or an application request".
Perhaps the cancellation token is cancelled when it get there? Something to do with the async changes?
### Reproduction
See customer reports
### Error and Stacktrace
```shell
| System.InvalidOperationException: Invalid operation. The connection is closed.
| at Microsoft.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
| at Microsoft.Data.SqlClient.SqlInternalTransaction.Rollback()
| at Microsoft.Data.SqlClient.SqlTransaction.Dispose(Boolean disposing)
| at Nevermore.Advanced.ReadTransaction.Dispose()
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.SaveResult(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 85
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.Record(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 56
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthCheckService.PerformHealthCheck(Machine machine, ITaskLog taskLogForMachine, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator, ExceptionHandling exceptionHandling, Action`2 customAction) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthCheckService.cs:line 92
| Octopus.Server version 2021.2.7650 (2021.2.7650+Branch.release-2021.2.Sha.0f176810b157f3de525844fbb6bd147186c70893)
| Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| System.Exception: Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| ---> Microsoft.Data.SqlClient.SqlException (0x80131904): A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The I/O operation has been aborted because of either a thread exit or an application request.)
| ---> System.ComponentModel.Win32Exception (995): The I/O operation has been aborted because of either a thread exit or an application request.
| at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result)
| at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
| at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
| --- End of stack trace from previous location ---
| at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
| --- End of stack trace from previous location ---
| at Nevermore.Transient.DbCommandExtensions.<>c__DisplayClass3_0.<<ExecuteReaderWithRetryAsync>b__0>d.MoveNext()
| --- End of stack trace from previous location ---
| at Nevermore.Transient.DbCommandExtensions.<>c__DisplayClass3_0.<<ExecuteReaderWithRetryAsync>b__0>d.MoveNext()
| --- End of stack trace from previous location ---
| at Nevermore.Transient.RetryPolicy.ExecuteActionAsync[TResult](Func`1 func)
| at Nevermore.Transient.DbCommandExtensions.ExecuteReaderWithRetryAsync(DbCommand command, RetryPolicy commandRetryPolicy, CommandBehavior commandBehavior, RetryPolicy connectionRetryPolicy, String operationName, CancellationToken cancellationToken)
| ClientConnectionId:689bb87c-aa3f-4c28-8621-cea63dea142d
| Error Number:995,State:0,Class:20
| ClientConnectionId before routing:4ed1a8ba-1f2c-4ec7-870b-01e24b467987
| Routing Destination:b5e9fe70b3a9.tr1.norwayeast1-a.worker.database.windows.net,11047
| --- End of inner exception stack trace ---
| at Nevermore.Transient.DbCommandExtensions.ExecuteReaderWithRetryAsync(DbCommand command, RetryPolicy commandRetryPolicy, CommandBehavior commandBehavior, RetryPolicy connectionRetryPolicy, String operationName, CancellationToken cancellationToken)
| at Nevermore.CommandExecutor.ExecuteReaderAsync(CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.ExecuteReaderAsync(PreparedCommand preparedCommand, CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.StreamAsync[TRecord](PreparedCommand command, CancellationToken cancellationToken)+MoveNext()
| at Nevermore.Advanced.ReadTransaction.LoadAsync[TDocument,TKey](TKey id, CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.LoadAsync[TDocument,TKey](TKey id, CancellationToken cancellationToken)
| at Octopus.Core.RelationalStorage.RawRelationalTransaction.LoadAsync[TDocument](String id, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Core\RelationalStorage\RawRelationalTransaction.cs:line 26
| at Octopus.Server.Web.Infrastructure.OctopusQueryExecutor.LoadAsync[TDocument](String id, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Web\Infrastructure\OctopusQueryExecutor.cs:line 225
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.SaveResult(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 85
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.Record(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 56
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthCheckService.PerformHealthCheck(Machine machine, ITaskLog taskLogForMachine, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator, ExceptionHandling exceptionHandling, Action`2 customAction) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthCheckService.cs:line 92
| Octopus.Server version 2021.2.7650 (2021.2.7650+Branch.release-2021.2.Sha.0f176810b157f3de525844fbb6bd147186c70893)
22:14:38 Verbose | Recording health check results
22:14:38 Fatal | Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| SQL Error 995 - A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The I/O operation has been aborted because of either a thread exit or an application request.)
| The I/O operation has been aborted because of either a thread exit or an application request.
22:14:38 Verbose | Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| SQL Error 995 - A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The I/O operation has been aborted because of either a thread exit or an application request.)
| The I/O operation has been aborted because of either a thread exit or an application request.
| Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| System.Exception: Exception occurred while executing a reader for `SELECT TOP 1 * FROM [dbo].[Machine] WHERE [Id] = @Id`
| ---> Microsoft.Data.SqlClient.SqlException (0x80131904): A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The I/O operation has been aborted because of either a thread exit or an application request.)
| ---> System.ComponentModel.Win32Exception (995): The I/O operation has been aborted because of either a thread exit or an application request.
| at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result)
| at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
| at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
| --- End of stack trace from previous location ---
| at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
| --- End of stack trace from previous location ---
| at Nevermore.Transient.DbCommandExtensions.<>c__DisplayClass3_0.<<ExecuteReaderWithRetryAsync>b__0>d.MoveNext()
| --- End of stack trace from previous location ---
| at Nevermore.Transient.DbCommandExtensions.<>c__DisplayClass3_0.<<ExecuteReaderWithRetryAsync>b__0>d.MoveNext()
| --- End of stack trace from previous location ---
| at Nevermore.Transient.RetryPolicy.ExecuteActionAsync[TResult](Func`1 func)
| at Nevermore.Transient.DbCommandExtensions.ExecuteReaderWithRetryAsync(DbCommand command, RetryPolicy commandRetryPolicy, CommandBehavior commandBehavior, RetryPolicy connectionRetryPolicy, String operationName, CancellationToken cancellationToken)
| ClientConnectionId:e09ffaf5-336d-447d-8650-de5369841aec
| Error Number:995,State:0,Class:20
| --- End of inner exception stack trace ---
| at Nevermore.Transient.DbCommandExtensions.ExecuteReaderWithRetryAsync(DbCommand command, RetryPolicy commandRetryPolicy, CommandBehavior commandBehavior, RetryPolicy connectionRetryPolicy, String operationName, CancellationToken cancellationToken)
| at Nevermore.CommandExecutor.ExecuteReaderAsync(CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.ExecuteReaderAsync(PreparedCommand preparedCommand, CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.StreamAsync[TRecord](PreparedCommand command, CancellationToken cancellationToken)+MoveNext()
| at Nevermore.Advanced.ReadTransaction.LoadAsync[TDocument,TKey](TKey id, CancellationToken cancellationToken)
| at Nevermore.Advanced.ReadTransaction.LoadAsync[TDocument,TKey](TKey id, CancellationToken cancellationToken)
| at Octopus.Core.RelationalStorage.RawRelationalTransaction.LoadAsync[TDocument](String id, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Core\RelationalStorage\RawRelationalTransaction.cs:line 26
| at Octopus.Server.Web.Infrastructure.OctopusQueryExecutor.LoadAsync[TDocument](String id, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Web\Infrastructure\OctopusQueryExecutor.cs:line 225
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.SaveResult(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 85
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthResultRecorder.Record(MachineHealthResult result, ITaskLog taskLog, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthResultRecorder.cs:line 56
| at Octopus.Server.Orchestration.ServerTasks.HealthCheck.HealthCheckService.PerformHealthCheck(Machine machine, ITaskLog taskLogForMachine, CancellationToken cancellationToken, IHealthResultCollator healthResultCollator, ExceptionHandling exceptionHandling, Action`2 customAction) in C:\BuildAgent\work\eb99e602a96dd63\source\Octopus.Server\Orchestration\ServerTasks\HealthCheck\HealthCheckService.cs:line 92
| Octopus.Server version 2021.2.7580 (2021.2.7580+Branch.release-2021.2.Sha.db69134412ffbf682ee48e345e2354b7834538ef)
22:14:38 Verbose | Recording health check results
```
### More Information
https://help.octopus.com/t/deployment-failed-but-all-steps-succeed/27244/9
https://octopusdeploy.slack.com/archives/CNHBHV2BX/p1633963377077000
https://octopus.zendesk.com/agent/tickets/76278
### Workaround
A workaround seems to be to set Pooling=false in the connection string.