最近在帮同事排查一个Conda创建环境失败的问题时,遇到了典型的"Unexpected Error"报错,错误信息中还夹杂着"SOCKS版本无法确定"的提示。这种问题在配置了网络代理的开发环境中相当常见,特别是当代理设置不正确或残留时。
完整的错误日志显示,Conda在尝试获取通知信息时失败,最终抛出了"ValueError: Unable to determine SOCKS version from socks://127.0.0.1:7890/"的错误。从环境变量部分可以看到ALL_PROXY和no_proxy都被设置了,这说明系统确实配置了代理。有趣的是,即使用户已经关闭了代理客户端,这些环境变量可能仍然存在,导致Conda继续尝试通过代理连接。
我注意到错误发生在requests库尝试建立SOCKS代理连接时。深入看调用栈,问题出在urllib3的SOCKSProxyManager初始化阶段,它无法从代理URL中解析出版本信息。这种情况通常发生在代理配置不完整或格式不正确时,比如只设置了代理地址但未明确指定SOCKS4或SOCKS5版本。
首先需要全面检查当前shell会话中的环境变量。很多人不知道的是,Linux系统中代理相关的环境变量至少有四种常见形式:
bash复制env | grep -i proxy
这个命令会显示所有包含"proxy"的环境变量。除了常见的http_proxy和https_proxy外,还要特别注意:
在我的案例中,发现用户同时设置了ALL_PROXY=socks://127.0.0.1:7890和no_proxy=localhost,127.0.0.1。理论上no_proxy应该能避免本地地址走代理,但Conda的某些请求仍然触发了代理错误,这说明环境变量的继承或应用可能存在问题。
Conda的配置文件优先级很多人容易混淆。实际上配置加载顺序是:
检查当前配置的最可靠方式是:
bash复制conda config --show
conda config --show-sources
第一个命令显示最终生效的配置,第二个命令显示配置来源。曾经遇到过一个案例,用户在家目录和/etc下都有.condarc文件,导致配置冲突。特别注意proxy_servers相关的配置项,它会直接覆盖环境变量的代理设置。
对于急需创建环境的情况,最简单的办法是绕过所有插件和代理:
bash复制CONDA_NO_PLUGINS=true conda create -n testenv python=3.8 --no-plugins
这个命令同时做了两件事:
如果问题确实出在某个插件(比如与代理相关的插件),这种方式通常能立即解决问题。但要注意,这只是临时解决方案,不是根本解决之道。
要彻底解决问题,需要系统性地清理代理配置:
bash复制unset ALL_PROXY
unset http_proxy
unset https_proxy
unset socks_proxy
unset no_proxy
bash复制rm -f ~/.condarc
重启终端会话,确保环境变量完全重置
验证网络连接是否正常:
bash复制conda search python
如果上述方法仍不奏效,可以尝试更深入的排查:
bash复制strace -e trace=network conda create -n testenv python=3.8 2>&1 | grep 'connect'
bash复制which python
python -c "import requests; print(requests.__version__)"
bash复制conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
为了避免这类问题反复出现,我总结了几条最佳实践:
conda config --remove-key清理无用配置有次在客户现场遇到一个特别棘手的问题,conda无论如何都无法创建环境。后来发现是因为系统预装了旧版本的conda,而用户又自行安装了新版本,导致二进制文件混用。最后通过完全卸载所有conda相关文件,然后重新安装解决了问题。这个经历让我意识到,有时候问题可能隐藏在意想不到的地方。
对于团队协作环境,我建议统一使用conda的离线安装模式,将所有包缓存在本地镜像中。这不仅能避免代理问题,还能提高安装速度。具体做法是设置本地channel优先级:
bash复制conda config --add channels file:///path/to/local/conda_mirror
conda config --set offline True
最后要提醒的是,conda的错误报告功能虽然有用,但在企业内网环境中可能需要特别注意隐私问题。可以通过以下配置禁用错误报告:
bash复制conda config --set report_errors false