Error select failed bad file descriptor

Hello everyone, I am trying to use a library found on the Internet for communication with network sockets, implementing a client-server communication. In the client after the connect () call runs a loop that executes 10 iterations, each iteration sends a message to the server and waits for a response. The server with the select() waits for connections, once received the message from the client sends a response. At the first iteration is all ok, at the second the server gives me a bad file descriptor error when it executes the select again, I can not deal with it, can anyone help? Thanks! Place the server code:

Hello everyone,
I am trying to use a library found on the Internet for communication with network sockets, implementing a client-server communication.
In the client after the connect () call runs a loop that executes 10 iterations, each iteration sends a message to the server and waits for a response.
The server with the select() waits for connections, once received the message from the client sends a response.
At the first iteration is all ok, at the second the server gives me a bad file descriptor error when it executes the select again, I can not deal with it, can anyone help? Thanks!
Place the server code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iostream>
#include "usock.h"
#include "usock_exception.h"

#include <string.h>


using namespace std;
using namespace usock;



int main() {
printf("Executing program prova_selectn");
int val=1;
char send_buffer[BUFRECV_SIZE];
char recv_buffer[BUFRECV_SIZE];

int max_sd, new_sd;
int clients[10];
int client_index=-1;

fd_set readset,tempset;

struct sockaddr_in addr;
socklen_t len = sizeof(struct sockaddr);


try {
ServerSocket ss(9999);

printf("Server: listening on port %dn", ss.localPort());

try{
ss.setSockOpt(SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
}
catch (exception e) {
printf("Reuse address exception");
exit(-1);
}

max_sd = ss.getSd();

for (int ind = 0; ind < 10; ind++) {
clients[ind]=-1;
}

FD_ZERO(&readset); //Resetto l'insieme dei descrittori per la lettura
FD_SET(ss.getSd(), &readset); //Setto il bit corrispondente al socket in ascolto nell'insieme dei descrittori per la lettura

while(1) {

tempset = readset;
if (select(max_sd+1, &tempset, NULL, NULL, NULL) < 0) {
perror("select()");
throw SocketException("Server: select error");
}

if (FD_ISSET(ss.getSd(), &tempset)) {
try {
int new_sd=accept(ss.getSd(), (struct sockaddr*)&addr, &len);
printf("Server: Accepted new connection on socket %dn", new_sd);


for (int i = 0; i < ss.getMaxconn(); i++) {
if (-1 == clients[i]) {
clients[i]=new_sd;

//aggiorna massimo indice in array di connessioni aperte
if (i > client_index) {
client_index=i;

}
FD_SET(new_sd, &readset);

//Aggiorno indice del massimo descrittore per la select
if (new_sd > max_sd) {
max_sd=new_sd;
}
break;
}
}
}
catch (exception e) {
printf("Server: accept() failedn");
}
}

else {
for (int i=0; i <= 10; i++) {
int temp_sd=clients[i];

if (-1 == temp_sd) {
printf("Server: Socket %d already closedn", temp_sd);
continue;
}

//Controllo se sono stati ricevuti dati sul socket corrente
if ( FD_ISSET(temp_sd, &tempset) ) {


try {
Socket temp_sock(temp_sd);
//Controllo il numero dei bytes ricevuti. Se è pari a zero la connessione lato client è stata chiusa. Rimuovo il descrittore dall'array delle connessioni aperte
if ( temp_sock.recv(recv_buffer, sizeof(recv_buffer)) == 0 ) {

printf("Server: Socket %d closed.n", temp_sd);
temp_sock.close();
FD_CLR(temp_sd, &readset);
clients[i]=-1;
}

else {

printf("Server: Received data %s from socket %dn", recv_buffer, temp_sd);
strcpy(send_buffer, recv_buffer);

try {

temp_sock.send(send_buffer, sizeof(send_buffer));

}
catch (exception e) {
printf("Send failed");

}

}

}
catch (exception e) {
printf("Receive failedn");
}
}
}
}
}

ss.close();
}
catch (exception e) {
exit(-1);
}
}

bharathk-9

iperf3: error — unable to send control message: Bad file descriptor

ISSUE: iperf3: error — unable to send control message: Bad file descriptor

Hello Team,

I’m running network testing on my two systems using the iperf3 command, where the testing is getting successful in some time and it’s failing in some time with the error message «iperf3: error — unable to send control message: Bad file descriptor». I assume the connectivity is the problem so to test the connectivity between both systems, I am running a ping test which is passed. In my next step, I am doing a retry in case of the first attempt failed in the iperf3 test. in my all attempt the results were the same(frequent failure with the error message).

Iperf Version: iperf 3.9 (cJSON 1.7.13)
Command used: iperf3 —client 10.0.0.4 —json

Help me to identify the issue and fix them, Thanks in advance.

swlars

Hi, we might need a bit more information to figure out your issue.

  1. What operating system are you using?
  2. Are you immediately retrying the test or is there some kind of sleep?
  3. Can you try with a more recent version of iperf3; the latest is 3.10.1.

bharathk-9

Hi @swlars,

Thank you for your response. please find my inline answers.

  1. What operating system are you using?
    ANS: Its Ubuntu 18.04.
  2. Are you immediately retrying the test or is there some kind of sleep?
    ANS: As of now I’m giving some sleep time but again it depends on the time the server starts up(which we don’t check as of now).
  3. Can you try with a more recent version of iperf3; the latest is 3.10.1.
    ANS: let me try and give you update.

As per your 2nd question there can be a chance the client start reaching to server as soon as the server starts up, let me try with some check when the server starts and from there ill give some sleep time. But want to know what is the expected sleep time we want to give so that client can reach to server after the server starts up.

Thanks,
Bharath K

davidhan1120

That message shows up when the port is not available. Check your firewall settings or the port that you are trying to test.

bharathk-9

I’m not mentioning any port along with command also I don’t have any firewall to block, as this is in my own system configured as private network.

davidhan1120

If you’re not mentioning any port with the command, by default it is going to need to use port 5001. Assuming that you are using this on your private network, you need to enable port forwarding on your home router.

A ping test only tests that the host is alive and uses an ICMP protocol, what you need to test is if a port is blocked.

ilham-Hamzah

TheRealDJ

The default iperf server port is 5201 which must be open on the server’s firewall.

brosahay

I am facing the same issue.

What operating system are you using?

PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

Are you immediately retrying the test, or is there some kind of sleep?

Nope.

Can you try with a more recent version of iperf3; the latest is 3.10.1.

$ iperf3 --version
iperf 3.9 (cJSON 1.7.13)

Let me try to get the latest.

The default iperf server port is 5201 which must be open on the server’s firewall.

The server is working fine when tested from another machine.

Rtoax

me too:

$ iperf3 -c 10.253.38.37
iperf3: error - unable to send control message: Bad file descriptor

embermctillhawk

Server computer is Ubuntu 20.04.4 LTS, x86-64
Client computer is Windows 10 Enterprise 2016 LTSB, v1607

iperf3 fails after exactly 49 seconds, every time, with
iperf3: error - select failed: Bad file descriptor

Running iperf3 3.11 on the Ubuntu machine, built from the tag here on github.

Running the other way around, with the server on windows and the client on ubuntu, no error is experienced, the test can run indefinitely.

TheRealDJ

Does Windows 10 do any outbound traffic blocking? I’d assume you needed to add a firewall exception to allow the inbound traffic. Not sure that this is the answer, but does the same issue occur with the Windows firewall disabled (or defender or whatever)?

embermctillhawk

Does Windows 10 do any outbound traffic blocking? I’d assume you needed to add a firewall exception to allow the inbound traffic. Not sure that this is the answer, but does the same issue occur with the Windows firewall disabled (or defender or whatever)?

No, running the same test w10e2016 -> w10e2016 doesn’t have the same issue.
I believe it is a behavior regression post-3.1.3, because all the windows computers are running 3.1.3, because I haven’t gotten around to figuring out how to build iperf3 for windows from source.

To clarify, the test runs for 49 seconds. It works perfectly for 49 seconds, and then terminates unexpectedly.
The command used on the ubuntu machine (3.11) is
iperf3 -s
The command used on the windows machine (3.1.3) is
iperf3 -c testmachine1 -b 64m -t 0

However, if the following commands are used instead,
iperf3 -s
iperf3 -c testmachine1 -b 64m -t 80
Then the test runs for exactly 80 seconds as expected.

Again, running the other way around,
ubuntu: iperf3 -c testmachine2 -b 64m -t 0
windows: iperf3 -s
The test runs indefinitely as expected.

I haven’t tried ubuntu-ubuntu yet, working on it now.

embermctillhawk

Critical update!
Connecting 3.11 to 3.11 works just fine.
It is a non-trivial versioning issue;

  • The only readily available version of iperf3 for Windows is 3.1.3
  • The most readily available version of iperf3 for Ubuntu is 3.7 (though 3.11 also exhibits this behavior)

If 3.7 or 3.11 is -s and 3.1.3 is -c, attempting to run an indefinite test -t 0 will fail after 49 seconds.
If 3.7 or 3.11 is -c and 3.1.3 is -s, attempting to run an indefinite test -t 0 will succeed.
If 3.7 or 3.11 is -s and 3.1.3 is -c, attempting to run a limited test -t 80 will not fail after 49 seconds, but will succeed.
If 3.7 is -s and 3.11 is -c, attempting to run an indefinite test -t 0 will succeed.

So the trouble is running post-3.1.3 as server and 3.1.3 as client. Different versions can connect to each other, which is probably desirable behavior, indefinite test behavior differs somehow, and we really really really really badly need updated public binaries.

MrCatEsq

This may be irrelevant to OPs case, but this message sometimes shown instead of «connection refused» when, for example, destination port blocked by a firewall or iperf3 server even not runned. I saw it when tried to connect from iperf 3.7 (latest Ubuntu LTS) to iperf 3.7 (previous Ubuntu LTS).

davidBar-On

…. this message sometimes shown instead of «connection refused» when, for example, destination port blocked by a firewall or iperf3 server even not runned. I saw it when tried to connect from iperf 3.7 ….

This specific issue was probably fixed by PR #1132. The fix is available only starting from version 3.10.

davidBar-On

@embermctillhawk, regarding:

The only readily available version of iperf3 for Windows is 3.1.3

Newer iperf3 version for Windows is available here (although not an official iperf3 site — maintained by BudMan).

markus2330

For me a different error message would already have helped. Maybe something along the lines like davidhan1120 commented on Dec 3, 2021, e.g.

the port is not available. Check your firewall settings or the port that you are trying to test.

If you really want to be beginner friendly, maybe also write that the server might not be running on the given host.

In my man page «control message» does not even occur once.

Recommend Projects

  • React photo

    React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo

    Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo

    Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo

    TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo

    Django

    The Web framework for perfectionists with deadlines.

  • Laravel photo

    Laravel

    A PHP framework for web artisans

  • D3 photo

    D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Visualization

    Some thing interesting about visualization, use data art

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo

    Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo

    Microsoft

    Open source projects and samples from Microsoft.

  • Google photo

    Google

    Google ❤️ Open Source for everyone.

  • Alibaba photo

    Alibaba

    Alibaba Open Source for everyone

  • D3 photo

    D3

    Data-Driven Documents codes.

  • Tencent photo

    Tencent

    China tencent open source team.

Before jumping right into the content directly, it’s essential to analyze the topics by asking some What and How questions. What is a Bad file descriptor error in Python? How do they occur? What are the ways that can help in solving this kind of errors? When we answer these questions, we can eventually understand the essence of this content by the end of this article.

When you don’t allow the code to perform the functions related to the file descriptors and the methods used, a Bad File Descriptor Error arises in Python, indicating the wrong way of implementing the code.

Kicking start with the basics always helps in understanding the core of the subject and hence assists in finding solutions to the most complex problems ever.

Cause of Errors Python

It’s salient to know that only by encountering many errors in code will you be highly proficient in the specific programming language. When you come across a new error, you try to detect where that error appeared from. Eventually, you start researching how to rectify the mistake.

There are even high chances of you exploring more and achieving various easier ways to apply the code better. At last, you will end up observing that your skills in the concept and knowledge about the same had grown vast.

Errors ought to occur in any possible programming language. In Python, errors generally occur when a particular code segment is not in compliance with the advised usage. Various errors are commonly faced by programmers, which include indentation, syntax, etc.

Rectifying these errors is no big deal when you review your code thoroughly. Have a complete understanding of the concepts and know enough about the right syntax to be used in the code.

“Other Commands Don’t Work After on_message” in Discord Bots

What are File Descriptors in Python?

In Python, file descriptors are integers(positive) that identify the kernel’s open files kept in a table of files. They are generally non-negative values.

If found to be negative, that indicates error or a “no value” condition. They assist in performing various functions related to files. Descriptors, in general, are a unique way that Python follows to manage attributes.

They mainly help in accessing files, other input/output devices like network sockets or pipes.

File descriptors do perform various operations. They include:

  • close(fd) – closes a file descriptor
  • dup(fd1) – duplicates file descriptor
  • fstat(fd) – returns the status of a file descriptor

The procedures mentioned above are elementary, and it’s important to know that file descriptors perform many more significant operations following the concept.

Understanding [Errno 9] Bad File Descriptor Error in Python

Have you encountered the following error message when you run your Python code when defining file directories or similar ones?

IOError:[Errno 9] Bad file descriptor

When you don’t allow the code to perform the functions related to the file descriptors and the methods used, these kinds of issues arise, indicating the wrong way of implementing the code.

Let’s understand this with an example:

<em>>>>file1=open(".bashrc")
>>>os.close(file1.fileno())
>>>def file1
close failed in file object destructor
IOError:[Errno 9] Bad file descriptor</em>

The below image shows a code with a bad file descriptor error in the Python shell.

[Errno 9] Bad File Descriptor Occurred in Python

In the above code, the del file will delete the reference of the file object specified. Now, as per the code written, the close function was not called. This forces the destructor to close the file. As this resulted in closing a file that wasn’t open in the first place, OS throws an error – Bad file descriptor.

Best Ways to Solve from [Errno 9] Bad File Descriptor in Python

  • Make sure you are using a valid file descriptor number. You will get a UNIX or Python Shell- Bad file descriptor error message when you fail using the right file descriptor number. This can cause issues when you open, close or use a file.
  • Use the right modes while handling file descriptors. For example to read from the file you need to use the read mode. When you choose the wrong mode, that triggers an error.
  • Analyse the concept and then implement the right functions at the right segments of your code.
  • Make certain whether the function to be executed through your code was executed already or not.

[Errno 9] Bad File Descriptor in Python Socket Module

Another main area in which this error is seen is in the Python socket – Socket error Bad file descriptor. When dealing with this kind of program, you can notice that you will find a Bad file descriptor error message is seen along with some issues in opening/closing or accessing the socket.

You can tackle this error by finding the right method of executing the function through the prescribed way of performing the function in accordance with the file descriptor.

One common thing that you can notice while handling errors in Python in relevance to files and file descriptors is that many of us fail to follow and implement the proper functions of the file descriptors defined in the code to perform the operations.

In addition to the above-discussed problems, this issue occurs while executing simple print statements too. You should focus on knowing if your specific file descriptors are available in the console that you are running.

This might seem simple when phrased but can cause a huge trauma to the programmer who has invested hours in writing the code. First, make sure that the specifies file descriptors are available in the console in which you run your program.

How to solve Bad File Descriptor in Python Socket module?

One way of handling this error is to calmly ignore the print statements and use alternative segments of code that serve a similar purpose.

Consider the following code –

from time import sleep
import socket
mcip = "mau5ville.com"
port = 25565
magic = "xFE"
s = socket.socket()
while 1:
    # Determine whether the server is up or down
    try:
        s.connect((mcip, port))
        s.send(magic)
        data = s.recv(1024)
        s.close()
        print(data)
    except Exception as e:
        print(e)
    sleep(60)

This error is caused when you specify a function to get executed when it has already completed doing the job. For instance, you order your code to close a file through your long lines of code. It shows an error like:

OSError: [Errno 9] Bad file descriptor

It means that the file defined in the program is already closed automatically while running the code. There lies no use in defining a separate method to perform the same task again.

[Resolved] NameError: Name _mysql is Not Defined

What is a bad file descriptor?

When we try to perform an operation/activity on closed (non-opened) files, a bad file descriptor error is generated. During such an error, you should look for possibilities where your file may get closed in your code.

What is a standard file descriptor?

In python file descriptors are integers(positive) that do the job of identifying the open files kept in a table of files by the kernel. They are generally non-negative values (0, 1, or 2).

What is Fcntl in Python?

fcntl is a library in Python that controls the file and I/O on file descriptors.

Conclusion

Bad file descriptor mainly arises due to many factors that were discussed in brief above. The main fact is that they occur when the right functions do not perform in association with the file descriptors.

With clear analysis and better knowledge of the concept, one can easily detect these errors and transform the code into a successful one.

References

  • Python open() function: file is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to open or an integer file descriptor of the file to wrap.
  • socket.socket(): If fileno is specified, the values for family, type, and proto auto-detects from the specified file descriptor.

Environment

RHEL 7
nfs-utils
rpc-statd.service

Issue

In rare circumstances, a bug in rpc.statd may result in the service failing to find an available reserved udp port during startup, and becoming stuck in a loop, repeatedly attempting to use a port that it closed. When this happens, rpc.statd does not complete its startup process, and outputs the message ‘rpc.statd[]: my_svc_run() — select: Bad file descriptor’ to the system log.

Resolution

This bug has not been resolved in RHEL 7, but has been corrected for RHEL 8.

Red Hat considers the bug extremely unlikely to occur, and recommends that any customers concerned that they may experience the bug implement a workaround.

Suggested workarounds include:

  • remove udp services from the /etc/services file, particularly between port 604 and port 658 — this will allow rpc.statd to use those ports, and rpc.statd will find an available udp port for its use

  • use NFS v4, which performs NFS locking through the same channel as NFS traffic, and does not require the separate rpc.statd for file locking

  • update to RHEL 8, where the bug is fixed

  • monitor system messages for the rpc.statd error, and restart the rpc-statd.service when the errors are seen

  • use rsyslog to detect the rpc.statd errors and restart rpc-statd.service automatically

/etc/rsyslog.d/fix-rpc.statd.conf
#####
module(load="omprog")

if ($programname == "rpc.statd" and $msg contains "select: Bad file descriptor") then {
    action(
        type="omprog"

        # execute this script when the condition is met
        binary="/etc/rsyslog.d/fix-rpc.statd"

        # rpc.statd outputs many errors very quickly, so
        # only execute the script every 10 seconds
        action.execOnlyOnceEveryInterval="10"
    )
    & stop
}
# discard a spurious message generated by executing the script
if ($programname == "rsyslogd" and $msg contains "has terminated, reaped by main-loop") then stop
#####


and the script can stop and restart the rpc-statd.service, logging a message to that effect:

/etc/rsyslog.d/fix-rpc.statd
#####
#!/bin/bash

echo "rpc.statd may have failed to find an available port... restarting the service" | logger -p daemon.notice -t fix-rpc.statd
sleep 0.25
(
    systemctl stop rpc-statd.service 2>&1
    sleep 0.25
    systemctl start rpc-statd.service 2>&1
    echo "Restarted rpc-statd.service"
) | logger -p daemon.notice -t fix-rpc.statd
#####


then restart rsyslog:
# systemctl restart rsyslog.service

Root Cause

The bug can occur because of the way that rpc.statd chooses a udp port during startup.

rpc.statd calls bindresvport() to obtain an available reserved udp port (port between 600 and 1024). It then checks the /etc/services file to determine whether any other services are likely to attempt to claim that reserved port. If the udp port is defined in the /etc/services file, rpc.statd again calls bindresvport() and tries again. If rpc.statd gets 100 reserved ports, but all are defined in /etc/services, or if no more reserved ports are available, rpc.statd then closes the ports it has opened, with the intent to use the first port it opened.

However, due to the bug, rpc.statd also closes the port that it first received from bindresvport(). When the program later attempts to use the closed port, it is invalid, and rpc.statd repeatedly logs the ‘select: Bad file descriptor’ error.

The bug is resolved in the upstream nfs-utils package with the following commit:

commit 3a5732152c60f8cefaa804db0b81e424e96ee657
Author: Chuck Lever <chuck.lever@oracle.com>
Date:   2015-09-16 11:18:02 -0400

    statd: statd_get_socket() should return open fds

    Tastky <tastky@gmail.com> reports:
    > There appears to be a bug in nfs-utils exposed by musl, which
    > makes rpc.statd loop with:
    >
    > my_svc_run() - select: Bad file descriptor

    OpenGroup says getservbyport(3) is supposed to return NULL when
    no entry exists for the specified port. But musl's getservbyport(3)
    never returns NULL (likely a bug).

    Thus statd_get_socket() tries bindresvport(3) 100 times, then gives
    up and returns the last socket it created. This should work fine,
    but there's a bug in the retry loop:

    Rich Felker <dalias@libc.org> says:
    > The logic bug is the count-down loop that closes all the temp
    > sockets. In the case where the loop terminates via break, it
    > leaves the last one open and only closes the extras. But in the
    > case where where the loop terminates via the end condition in the
    > for statement, the close loop closes all the sockets _including_
    > the one it intends to use.

    (emphasis mine). The closed socket fd is then passed to select(2).

    See also: http://www.openwall.com/lists/musl/2015/08

    The fix is to perform the loop termination test before adding sockfd
    to the set of fds to be closed. As additional clean ups, remove the
    use of the variable-length stack array, and switch to variable names
    that better document the purpose of this logic.

    Reported-by: Tastky <tastky@gmail.com>
    Fixes: eb8229338f06 ("rpc.statd: Fix socket binding loop.")
    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
    Signed-off-by: Steve Dickson <steved@redhat.com>

Diagnostic Steps

messages such as the following are repeatedly logged in the system’s message log:

server.example.com rpc.statd[2960]: my_svc_run() - select: Bad file descriptor
server.example.com rpc.statd[2960]: my_svc_run() - select: Bad file descriptor
server.example.com rpc.statd[2960]: my_svc_run() - select: Bad file descriptor
server.example.com rpc.statd[2960]: my_svc_run() - select: Bad file descriptor


  • Product(s)

  • Red Hat Enterprise Linux


  • Component

  • nfs-utils


  • Tags

  • nfs3

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Понравилась статья? Поделить с друзьями:
  • Error security violation error offending command
  • Error seculauncher failed to start application 2000 0x000036b1 ок
  • Error secretorprivatekey must have a value
  • Error searching for packages юнити
  • Error searching for packages unityeditor